Introduction

Washington University Medical Center Redevelopment Corporation is a partnership between BJC Health Care and Washington University School of Medicine and works to improve the quality of life for the neighborhoods surrounding the medical campus. In order to achieve this goal in Forest Park Southeast and the Central West End , WUMCRC has invested millions of dollars toward regenerating the market for private investment in businesses and real estate, enhancing human and social service opportunities, and improving the level of physical and personal security.

One way we work to improve the level of physical & personal security is the analysis and distribution of data. The original source of this crime data is http://slmpd.org/crimereports.shtml. This notebook uses primarily compstatr to access and clean the crime data.

R Markdown

Tidy data

Create an Index

i <- cs_create_index()

Get Data - 2019

update <- cs_last_update()
update <- strsplit(update, " ")[[1]]
c_month <- update[[1]]
c_year <- as.numeric(update[[2]])
yearList19 <- cs_get_data(year = c_year, index = i)

Download Current Month

cs_validate(yearList19, year = 2019)
[1] TRUE
totalCrimes19 <- cs_collapse(yearList19)
print(c_month)
[1] "August"
crimes19 <- cs_extract_month(yearList19, month = "August")

Clean & Categorize Data - 2019

cs_filter_count removes negative counts. Negative counts, -1, in the count column means that the crime, or charge in this specific observation has either been deemed unfounded, or the crime has been up coded. We do not want to map this data.

Many of the analyses we conduct include comparisons between violent & non-violent crime, comparisons on the amount of crimes happening in each crime cateogy over time, and if crimes occur during the day or at night. The following code ceates variables to conduct these analyses.

cs_crime_cat creates a variable with the names of the crime.

cs_crime creates a logic variable and codes violent crimes as TRUE and non-violent crimes as FALSE

cs_parse_date creates two columns separating the Date Occur variable. The two colums are as follows: one contains the date - month, date, and year, and the other contains the hour and minute. This is used because crimes coded in the most recent month, can contain dates that occured, in previous months or years & in this report we only want to map the crimes that occured in the past month.

filter is a dplyr function that filters out any dates that occur before the our selected date, and also filters out crimes that did not happen in either District 2 or district 5.

mutate adds a variable that codes and labels the days of the week for each crime that occurred, and creates another time of day variable

tidyCrimes19 <- crimes19 %>% 
  cs_filter_count(., var = count) %>%
  cs_filter_crime(., var = crime, "part 1") %>%
  cs_crime_cat(., var = crime, crimeCatNum, "numeric") %>%
  cs_crime_cat(., var = crime, crimeCatName, "string") %>%
  cs_crime(., var = crime, violent, "violent") %>%
  cs_crime(., var = crime, property, "property") %>%
  cs_parse_date(., date_occur, dateVar = dateOcc, timeVar = timeOcc) %>%
  filter(dateOcc >= as.Date("2019-08-01")) %>%
  filter(district == 2 | district == 5) %>%
  mutate(weekday = wday(dateOcc, label = TRUE)) %>%
  mutate(tod = timeOcc)
tidyCrimes19$neighborhood <- as.numeric(tidyCrimes19$neighborhood)

strptime and format takes the new time variable and formats it to a character so that we can determine if the crime occured at day or at night, and creates a second coded variable that labels each observations as day or night based on the newly formated time variable.

select drops the unneeded variables.

cs_missing_XY determines what data does not have x & y coordinates, and therefore cannot be accurately mapped.

cs_replace0 replaces missing x & y coordinates with NA, and drops the missing data.

tidyCrimes19$tod <- strptime(tidyCrimes19$tod, tz = "America/Chicago", "%H:%M")
tidyCrimes19$tod <- format(tidyCrimes19$tod, format = "%H%M%S")
tidyCrimes19 <- tidyCrimes19 %>%
  mutate(., dayNight = ifelse(tod >= "180000" & tod < "600000", "Night", "Day")) %>% 
  dplyr::select(-dateTime, -tod, -flag_crime, -flag_administrative, -flag_unfounded, -flag_cleanup)
tidyCrimes19 <- cs_missingXY(tidyCrimes19, varX = x_coord, varY = y_coord, newVar = missing)
table(tidyCrimes19$missing)

FALSE  TRUE 
  735     4 
tidyCrimes19 <- tidyCrimes19 %>% 
  cs_replace0(., var = x_coord) %>%
  cs_replace0(., var = y_coord) %>% 
  filter(., missing == FALSE) 

Get Data - 2018

yearList18 <- cs_get_data(year = 2018, index = i)

Data Preperation

cs_validate(yearList18, year = 2018)
[1] TRUE

Download Last Year’s Month

totalCrimes18 <- cs_collapse(yearList18)
crimes18 <- cs_extract_month(yearList18, month = "August")

Clean & Categorize Data - 2018

tidyCrimes18 <- crimes18 %>% 
  cs_filter_count(., var = count) %>%
  cs_filter_crime(., var = crime, "part 1") %>%
  cs_crime_cat(., var = crime, crimeCatNum, "numeric") %>%
  cs_crime_cat(., var = crime, crimeCatName, "string") %>%
  cs_crime(., var = crime, violent, "violent") %>%
  cs_crime(., var = crime, property, "property") %>%
  cs_parse_date(., date_occur, dateVar = dateOcc, timeVar = timeOcc) %>%
  filter(dateOcc >= as.Date("2018-08-01") & dateOcc <= as.Date("2018-08-31")) %>%
  filter(district == 2 | district == 5) %>%
  mutate(weekday = wday(dateOcc, label = TRUE)) %>%
  mutate(tod = timeOcc)
tidyCrimes18$neighborhood <- as.numeric(tidyCrimes18$neighborhood)
tidyCrimes18$tod <- strptime(tidyCrimes18$tod, tz = "America/Chicago", "%H:%M")
tidyCrimes18$tod <- format(tidyCrimes18$tod, format = "%H%M%S")
tidyCrimes18 <- tidyCrimes18 %>%
  mutate(., dayNight = ifelse(tod >= "180000" & tod < "600000", "Night", "Day")) %>% 
  dplyr::select(-dateTime, -tod, -flag_crime, -flag_administrative, -flag_unfounded, -flag_cleanup)
tidyCrimes18 <- cs_missingXY(tidyCrimes18, varX = x_coord, varY = y_coord, newVar = missing)
table(tidyCrimes18$missing)

FALSE  TRUE 
  747     9 
tidyCrimes18 <- tidyCrimes18 %>% 
  cs_replace0(., var = x_coord) %>%
  cs_replace0(., var = y_coord) %>% 
  filter(., missing == FALSE)

Combine 2018 & 2019

augustCrimes <- rbind(tidyCrimes18, tidyCrimes19)

Create Spatial Objects

crimes18_sf <- cs_projectXY(tidyCrimes18, varX = x_coord, varY = y_coord, crs = 102696)
crimes19_sf <- cs_projectXY(tidyCrimes19, varX = x_coord, varY = y_coord, crs = 102696)
augustCrimes_sf <- cs_projectXY(augustCrimes, varX = x_coord, varY = y_coord, crs = 102696)

Prep for Data by Neighborhood

sa <- c(39,28,38,51,53,54,58,46,47,48,48)
dst2 <- c(7:15,27:29, 39:45,81,82,87,88)
dst5 <- c(38,46:58,78)

Mapping

One way we work to improve the level of physical & personal security is the analysis and distribution of crime data and statistics. The original source of this crime data is http://slmpd.org/crimereports.shtml. This notebook takes the data that was previously cleaned and maps the data.

Load Spatial Data

Coordinates

xyfpse <- c(-90.2679, -90.2423, 38.6176, 38.6334)
xycwe <- c(-90.2759, -90.2368, 38.6286, 38.6552)
xybot <- c(-90.2619, -90.2409, 38.6165, 38.6296)
xydbp <- c(-90.2869, -90.2726, 38.6433, 38.6566)
xysdb <- c(-90.3026, -90.2827, 38.6456, 38.6571)
xywe <- c(-90.3020, -90.2712, 38.6517, 38.6710)
xyvp <- c(-90.2803, -90.2712, 38.6517, 38.6622)
xyac <- c(-90.2744, -90.2609, 38.6505, 38.6661)
xyfp <- c(-90.2648, -90.2543, 38.6493, 38.6655)
xylp <- c(-90.2588, -90.2437, 38.6481, 38.6624)
xyvd <- c(-90.2520, -90.2304, 38.6426, 38.6585)
xymc <- c(-90.2678, -90.2515, 38.6305, 38.6411)
xyctx <- c(-90.2581, -90.2419, 38.6299, 38.6386)
xygrv <- c(-90.2662, -90.2440, 38.6238, 38.6318)
xydst2 <- c(-90.3203, -90.2297, 38.5613, 38.6493)
xydst5 <- c(-90.3080, -90.2132, 38.6273, 38.6962)

Open Street Map from Mapbox - Basemap Tile Imagery

Spatial Data from the City Of St. Louis

nhoods_sf <- gw_get_data("Neighborhoods", "sf") %>% 
   rename(neighborhood = NHD_NUM)
trying URL 'https://www.stlouis-mo.gov/data/upload/data-files/nbrhds_wards.zip'
Content type 'application/x-zip-compressed' length 184305 bytes (179 KB)
downloaded 179 KB
sa_sf <- nhoods_sf %>% 
  filter(., NHD_NUM %in% sa) %>% 
fpse <- filter(nhoods_sf, NHD_NUM == 39 )
Error in !inherits(x, "sf") : object 'NHD_NUM' not found

Load External Data

Population Data

load(here("data/nbhd_pop10.rda"))

Spatial

Combine Population & Neighborhood Spatial Data by Police District

Oganize & Filter Crime Data by Neighborhood

dst_2 <- tidyCrimes19 %>% 
  filter(., neighborhood %in% dst2) %>% 
  group_by(., neighborhood) %>%
  count() %>% 
  rename(crimeTotal = n) %>%
  left_join(nbhd_pop10, by = "neighborhood") %>% 
  mutate(., crimeRate = (crimeTotal/pop10)*1000) %>% 
  drop_na()
dst_2_pop <- left_join(nhoods_sf, dst_2, by = "neighborhood") %>% 
  st_transform(crs = 102696) %>%
  drop_na() %>% 
  subset(., neighborhood != 88)
  
# dst2 <- left_join(nhoods_sf, by = "neighborhood")
dst_5 <- tidyCrimes19 %>% 
  filter(., neighborhood %in% dst5) %>% 
  group_by(., neighborhood) %>%
  count() %>% 
  rename(crimeTotal = n) %>%
  left_join(nbhd_pop10, by = "neighborhood") %>% 
  mutate(., crimeRate = (crimeTotal/pop10)*1000) %>% 
  drop_na()
dst_5_pop <- left_join(nhoods_sf, dst_5, by = "neighborhood") %>% 
  st_transform(crs = 102696) %>%
  drop_na()

FPSE, BOT, CWE, MC

Map Creation

FPSE
fpse_total_tm <- tm_shape(fpse_tiles) +
  tm_rgb() +
  nhoods_sf %>%
  filter(., NHD_NUM == 39) %>% 
  tm_shape() +
    tm_fill(col = "#9ecae1", 
            alpha = .5) +
    tm_borders(col = "black", 
               lwd = 2, 
               lty = "dashed") +
  filter(crimes19_sf, 
         neighborhood == 39) %>%
  tm_shape() +
    tm_bubbles(size = .25, 
               col = "crimeCatName", 
               palette = "Set1", 
               title.col = "Part 1 Crimes") +
  tm_credits("© Mapbox, © OpenStreetMap", position = c("left", "BOTTOM")) +
  tm_layout(
    main.title = "FPSE Total Crime - August 2019",
    frame = FALSE,
    legend.bg.color = "white", 
    legend.frame=TRUE,
    legend.outside = FALSE,
    legend.position = c("right", "bottom"))
fpse_total_tm

fpse_dn_tm <- tm_shape(fpse_tiles) +
  tm_rgb() +
  nhoods_sf %>%
  filter(., NHD_NUM == 39) %>% 
  tm_shape() +
    tm_fill(col = "#9ecae1", 
            alpha = .5) +
    tm_borders(col = "black", 
               lwd = 2, 
               lty = "dashed") +
  filter(crimes19_sf, 
         neighborhood == 39) %>%
  tm_shape() +
    tm_bubbles(size = .25, 
               col = "dayNight", 
               palette = "-RdBu", 
               title.col = "Time of Crimes") +
  tm_credits("© Mapbox, © OpenStreetMap", position = c("left", "BOTTOM")) +
  tm_layout(
    main.title = "FPSE Time of Crimes - August 2019",
    frame = FALSE,
    legend.bg.color = "white", 
    legend.frame=TRUE,
    legend.outside = FALSE,
    legend.position = c("right", "bottom"))
fpse_dn_tm

fpse_vlnt_tm <- tm_shape(fpse_tiles) +
  tm_rgb() +
  nhoods_sf %>%
  filter(., NHD_NUM == 39) %>% 
  tm_shape() +
    tm_fill(col = "#9ecae1", 
            alpha = .5) +
    tm_borders(col = "black", 
               lwd = 2, 
               lty = "dashed") +
  filter(crimes19_sf, 
         neighborhood == 39) %>%
  tm_shape() +
    tm_bubbles(size = .25, 
               col = "violent", 
               palette = "Reds", 
               title.col = "Violent") +
  tm_credits("© Mapbox, © OpenStreetMap", position = c("left", "BOTTOM")) +
  tm_layout(
    main.title = "FPSE Violent Crime - August 2019",
    frame = FALSE,
    legend.bg.color = "white", 
    legend.frame=TRUE,
    legend.outside = FALSE,
    legend.position = c("right", "bottom"))
fpse_vlnt_tm

crimes19_sf %>%
  filter(neighborhood == 39) %>%
  smooth_map(., bandwidth = 0.5, style = "pretty",
  cover = fpse) -> fpse_densities

  |                                                                                                                                       
  |                                                                                                                                 |   0%
  |                                                                                                                                       
  |=============                                                                                                                    |  10%
  |                                                                                                                                       
  |=======================================                                                                                          |  30%
  |                                                                                                                                       
  |================================================================                                                                 |  50%
  |                                                                                                                                       
  |==========================================================================================                                       |  70%
  |                                                                                                                                       
  |====================================================================================================================             |  90%
  |                                                                                                                                       
  |=================================================================================================================================| 100%
fpse_den_tm <- tm_shape(fpse_tiles) +
  tm_rgb() +
  nhoods_sf %>%
  filter(., NHD_NUM == 39) %>% 
  tm_shape() +
    tm_fill(col = NA, 
            alpha = .5) +
    tm_borders(col = "black", 
               lwd = 2, 
               lty = "dashed") +
  tm_shape(fpse_densities$polygons) +
  tm_fill(col = "level", palette = "BuPu", alpha = .60, 
    title = expression("Crimes per " * km^2)) +
  tm_credits("© Mapbox, © OpenStreetMap", position = c("left", "BOTTOM")) +
  tm_layout(
    main.title = "FPSE Crime Density - August 2019",
    frame = FALSE,
    legend.bg.color = "white", 
    legend.frame=TRUE,
    legend.outside = FALSE,
    legend.position = c("right", "bottom"))
fpse_den_tm

Grove CID
grove_crimes <- st_intersection(crimes19_sf, grove_cid)
attribute variables are assumed to be spatially constant throughout all geometries
fpse_grove_tm <- tm_shape(grv_tiles) +
  tm_rgb() +
  nhoods_sf %>%
  filter(., NHD_NUM == 39) %>% 
  tm_shape() +
    tm_borders(col = "black", 
               lwd = 2, 
               lty = "dashed") +
  tm_shape(grove_cid) +
    tm_fill(col = "#9ecae1", 
            alpha = .5) +
    tm_borders(col = "black", 
               lwd = 1, 
               lty = "solid") +
  tm_shape(grove_crimes) +
    tm_bubbles(size = .25, 
               col = "crimeCatName", 
               palette = "Set1", 
               title.col = "Part 1 Crimes") +
  tm_credits("© Mapbox, © OpenStreetMap", position = c("left", "BOTTOM")) +
  tm_layout(
    main.title = "Grove CID Total Crime - August 2019",
    frame = FALSE,
    legend.bg.color = "white", 
    legend.frame=TRUE,
    legend.outside = FALSE,
    legend.position = c("right", "bottom"))
fpse_grove_tm

CWE
cwe_total_tm <- tm_shape(cwe_tiles) +
  tm_rgb() +
  nhoods_sf %>%
  filter(., NHD_NUM == 38) %>% 
  tm_shape() +
    tm_fill(col = "#9ecae1", 
            alpha = .5) +
    tm_borders(col = "black", 
               lwd = 2, 
               lty = "dashed") +
  filter(crimes19_sf, 
         neighborhood == 38) %>%
  tm_shape() +
    tm_bubbles(size = .25, 
               col = "crimeCatName", 
               palette = "Set1", 
               title.col = "Part 1 Crimes") +
  tm_credits("© Mapbox, © OpenStreetMap", position = c("left", "BOTTOM")) +
  tm_layout(
    main.title = "CWE Total Crime - August 2019",
    frame = FALSE,
    legend.bg.color = "white", 
    legend.frame=TRUE,
    legend.outside = FALSE,
    legend.position = c("right", "bottom"))
cwe_total_tm

cwe_dn_tm <- tm_shape(cwe_tiles) +
  tm_rgb() +
  nhoods_sf %>%
  filter(., NHD_NUM == 38) %>% 
  tm_shape() +
    tm_fill(col = "#9ecae1", 
            alpha = .5) +
    tm_borders(col = "black", 
               lwd = 2, 
               lty = "dashed") +
  filter(crimes19_sf, 
         neighborhood == 38) %>%
  tm_shape() +
    tm_bubbles(size = .25, 
               col = "dayNight", 
               palette = "-RdBu", 
               title.col = "Time of Crimes") +
  tm_credits("© Mapbox, © OpenStreetMap", position = c("left", "BOTTOM")) +
  tm_layout(
    main.title = "CWE Total Crime - August 2019",
    frame = FALSE,
    legend.bg.color = "white", 
    legend.frame=TRUE,
    legend.outside = FALSE,
    legend.position = c("right", "bottom"))
cwe_dn_tm

cwe_vlnt_tm <- tm_shape(cwe_tiles) +
  tm_rgb() +
  nhoods_sf %>%
  filter(., NHD_NUM == 38) %>% 
  tm_shape() +
    tm_fill(col = "#9ecae1", 
            alpha = .5) +
    tm_borders(col = "black", 
               lwd = 2, 
               lty = "dashed") +
  filter(crimes19_sf, 
         neighborhood == 38) %>%
  tm_shape() +
    tm_bubbles(size = .25, 
               col = "violent", 
               palette = "Reds", 
               title.col = "Violent") +
  tm_credits("© Mapbox, © OpenStreetMap", position = c("left", "BOTTOM")) +
  tm_layout(
    main.title = "CWE Time of Crimes - August 2019",
    frame = FALSE,
    legend.bg.color = "white", 
    legend.frame=TRUE,
    legend.outside = FALSE,
    legend.position = c("right", "bottom"))
cwe_vlnt_tm

cwe_densities <- crimes19_sf %>%
  filter(neighborhood == 38) %>%
  smooth_map(., bandwidth = 0.5, style = "pretty",
  cover = cwe)

  |                                                                                                                                       
  |                                                                                                                                 |   0%
  |                                                                                                                                       
  |=============                                                                                                                    |  10%
  |                                                                                                                                       
  |=======================================                                                                                          |  30%
  |                                                                                                                                       
  |================================================================                                                                 |  50%
  |                                                                                                                                       
  |==========================================================================================                                       |  70%
  |                                                                                                                                       
  |====================================================================================================================             |  90%
  |                                                                                                                                       
  |=================================================================================================================================| 100%
cwe_den_tm <- tm_shape(cwe_tiles) +
  tm_rgb() +
  nhoods_sf %>%
  filter(., NHD_NUM == 38) %>% 
  tm_shape() +
    tm_fill(col = NA, 
            alpha = .5) +
    tm_borders(col = "black", 
               lwd = 2, 
               lty = "dashed") +
  tm_shape(cwe_densities$polygons) +
  tm_fill(col = "level", palette = "BuPu", alpha = .60, 
    title = expression("Crimes per " * km^2)) +
  tm_credits("© Mapbox, © OpenStreetMap", position = c("left", "BOTTOM")) +
  tm_layout(
    main.title = "CWE Crime Density- August 2019",
    frame = FALSE,
    legend.bg.color = "white", 
    legend.frame=TRUE,
    legend.outside = FALSE,
    legend.position = c("right", "top"))
cwe_den_tm

Medical Campus
mc_crimes <- st_intersection(crimes19_sf, med_campus)
attribute variables are assumed to be spatially constant throughout all geometries
cwe_mc_tm <- tm_shape(mc_tiles) +
  tm_rgb() +
  nhoods_sf %>%
  filter(., NHD_NUM == 38) %>% 
  tm_shape() +
    tm_borders(col = "black", 
               lwd = 2, 
               lty = "dashed") +
  tm_shape(med_campus) +
    tm_fill(col = "#9ecae1", 
            alpha = .5) +
    tm_borders(col = "black", 
               lwd = 1, 
               lty = "solid") +
  tm_shape(mc_crimes) +
    tm_bubbles(size = .25, 
               col = "crimeCatName", 
               palette = "Set1", 
               title.col = "Part 1 Crimes") +
  tm_credits("© Mapbox, © OpenStreetMap", position = c("left", "BOTTOM")) +
  tm_layout(
    main.title = "Med. Campus Total Crime - August 2019",
    frame = FALSE,
    legend.bg.color = "white", 
    legend.frame=TRUE,
    legend.outside = FALSE,
    legend.position = c("right", "top"))
cwe_mc_tm

Cortex
ctx_crimes <- st_intersection(crimes19_sf, cortex)
attribute variables are assumed to be spatially constant throughout all geometries
cwe_ctx_tm <- tm_shape(ctx_tiles) +
  tm_rgb() +
  nhoods_sf %>%
  filter(., NHD_NUM == 38) %>% 
  tm_shape() +
    tm_borders(col = "black", 
               lwd = 2, 
               lty = "dashed") +
  tm_shape(cortex) +
    tm_fill(col = "#9ecae1", 
            alpha = .5) +
    tm_borders(col = "black", 
               lwd = 1, 
               lty = "solid") +
  tm_shape(ctx_crimes) +
    tm_bubbles(size = .25, 
               col = "crimeCatName", 
               palette = "Set1", 
               title.col = "Part 1 Crimes") +
  tm_credits("© Mapbox, © OpenStreetMap", position = c("left", "BOTTOM")) +
  tm_layout(
    main.title = "Cortex Total Crime - August 2019",
    frame = FALSE,
    legend.bg.color = "white", 
    legend.frame=TRUE,
    legend.outside = FALSE,
    legend.position = c("right", "top"))
cwe_ctx_tm

Botanical Heights
bot_total_tm <- tm_shape(bot_tiles) +
  tm_rgb() +
  nhoods_sf %>%
  filter(., neighborhood == 28) %>% 
  tm_shape() +
    tm_fill(col = "#9ecae1", 
            alpha = .5) +
    tm_borders(col = "black", 
               lwd = 2, 
               lty = "dashed") +
  filter(crimes19_sf, 
         neighborhood == 28) %>%
  tm_shape() +
    tm_bubbles(size = .25, 
               col = "crimeCatName", 
               palette = "Set1", 
               title.col = "Part 1 Crimes") +
  tm_credits("© Mapbox, © OpenStreetMap", position = c("left", "BOTTOM")) +
  tm_layout(
    main.title = "Botanical Heights Total Crime - August 2019",
    frame = FALSE,
    legend.bg.color = "white", 
    legend.frame=TRUE,
    legend.outside = TRUE,
    legend.position = c("left", "top"))
bot_total_tm

District 2 Density Maps
dst2_rateMap <- tm_shape(dst2_tiles) +
  tm_rgb() +
  tm_shape(dst_2_pop) +
  tm_polygons(col = "crimeRate",
              palette = "BuPu",
              style = "jenks",
              title = "Crimes per 1,000 Residents") +
  tm_text("neighborhood", shadow=TRUE) +
  tm_layout(
    main.title = "District 2 Crime Rates - August 2019",
    frame = FALSE,
    legend.bg.color = "white", 
    legend.frame=TRUE,
    legend.outside = TRUE,
    legend.position = c("right", "bottom")) 
dst2_rateMap

dst5_rateMap <- tm_shape(dst5_tiles) +
  tm_rgb() +
  tm_shape(dst_5_pop) +
  tm_polygons(col = "crimeRate",
              palette = "BuPu",
              style = "jenks",
              title = "Crimes per 1,000 Residents") +
  tm_text("neighborhood", shadow=TRUE) +
  tm_layout(
    main.title = "District 5 Crime Rates - August 2019",
    frame = FALSE,
    legend.bg.color = "white", 
    legend.frame=TRUE,
    legend.outside = TRUE,
    legend.position = c("right", "bottom")) 
dst5_rateMap

Save Maps

Clean Workspace

LS0tDQp0aXRsZTogIlNhaW50IExvdWlzIENpdHkgQ3JpbWUgRGF0YSAtIE1vbnRobHkgUmVwb3J0cyINCmF1dGhvcjogIkplcyBTdGV2ZW5zLCBNLkEuIg0KZGF0ZTogJyhgciBmb3JtYXQoU3lzLnRpbWUoKSwgIiVCICVkLCAlWSIpYCknDQpvdXRwdXQ6DQogIGdpdGh1Yl9kb2N1bWVudDogZGVmYXVsdA0KICBodG1sX25vdGVib29rOiBkZWZhdWx0DQotLS0NCg0KYGBge3IgU2V0dXAsIGluY2x1ZGU9RkFMU0V9DQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpDQpgYGANCg0KIyMgSW50cm9kdWN0aW9uIA0KDQpbV2FzaGluZ3RvbiBVbml2ZXJzaXR5IE1lZGljYWwgQ2VudGVyIFJlZGV2ZWxvcG1lbnQgQ29ycG9yYXRpb25dKGh0dHA6Ly93dW1jcmMuY29tKSBpcyBhIHBhcnRuZXJzaGlwIGJldHdlZW4gQkpDIEhlYWx0aCBDYXJlIGFuZCBXYXNoaW5ndG9uIFVuaXZlcnNpdHkgU2Nob29sIG9mIE1lZGljaW5lIGFuZCB3b3JrcyB0byBpbXByb3ZlIHRoZSBxdWFsaXR5IG9mIGxpZmUgZm9yIHRoZSBuZWlnaGJvcmhvb2RzIHN1cnJvdW5kaW5nIHRoZSBtZWRpY2FsIGNhbXB1cy4gSW4gb3JkZXIgdG8gYWNoaWV2ZSB0aGlzIGdvYWwgaW4gRm9yZXN0IFBhcmsgU291dGhlYXN0IGFuZCB0aGUgQ2VudHJhbCBXZXN0IEVuZCAsIFdVTUNSQyBoYXMgaW52ZXN0ZWQgbWlsbGlvbnMgb2YgZG9sbGFycyB0b3dhcmQgcmVnZW5lcmF0aW5nIHRoZSBtYXJrZXQgZm9yIHByaXZhdGUgaW52ZXN0bWVudCBpbiBidXNpbmVzc2VzIGFuZCByZWFsIGVzdGF0ZSwgZW5oYW5jaW5nIGh1bWFuIGFuZCBzb2NpYWwgc2VydmljZSBvcHBvcnR1bml0aWVzLCBhbmQgaW1wcm92aW5nIHRoZSBsZXZlbCBvZiBwaHlzaWNhbCBhbmQgcGVyc29uYWwgc2VjdXJpdHkuDQoNCk9uZSB3YXkgd2Ugd29yayB0byBpbXByb3ZlIHRoZSBsZXZlbCBvZiBwaHlzaWNhbCAmIHBlcnNvbmFsIHNlY3VyaXR5IGlzIHRoZSBhbmFseXNpcyBhbmQgZGlzdHJpYnV0aW9uIG9mIGRhdGEuIFRoZSBvcmlnaW5hbCBzb3VyY2Ugb2YgdGhpcyBjcmltZSBkYXRhIGlzIDxodHRwOi8vc2xtcGQub3JnL2NyaW1lcmVwb3J0cy5zaHRtbD4uIFRoaXMgbm90ZWJvb2sgdXNlcyBwcmltYXJpbHkgYGNvbXBzdGF0cmAgdG8gYWNjZXNzIGFuZCBjbGVhbiB0aGUgY3JpbWUgZGF0YS4gDQoNCiMjIFIgTWFya2Rvd24NCg0KYGBge3IgTG9hZCBEZXBlbmRlbmNpZXMsIGluY2x1ZGUgPSBGQUxTRX0NCiMgdGlkeXZlcnNlIHBhY2thZ2VzDQpsaWJyYXJ5KGdncGxvdDIpICAgICAgICMgcGxvdHRpbmcgZGF0YQ0KbGlicmFyeShzdHJpbmdyKSAgICAgICAjIHdyYXBwZXJzIGZvciBjb21tb24gc3RyaW5nIG9wZXJhdGlvbnMNCmxpYnJhcnkodGlkeXIpICAgICAgICAgIyB0aWR5IGRhdGENCmxpYnJhcnkoZHBseXIpICAgICAgICAgIyBkYXRhIG1hbmlwdWxhdGlvbg0KbGlicmFyeShtYWdyaXR0cikgICAgICAjIHBpcGUgb3BlcmF0b3INCmxpYnJhcnkocmVhZHhsKSAgICAgICAgIyByZWFkICYgd3JpdGUgZXhjZWwgZmlsZXMNCmxpYnJhcnkobHVicmlkYXRlKQ0KDQojIHNwYXRpYWwgcGFja2FnZXMNCmxpYnJhcnkodG1hcCkgICAgICAgICAjIG1hcCBsYXlvdXRzDQpsaWJyYXJ5KHRtYXB0b29scykgICAgIyB0b29scyBmb3IgaGFuZGVsaW5nIHNwYXRpYWwgDQpsaWJyYXJ5KG9sZHRtYXB0b29scykNCmxpYnJhcnkoc2YpICAgICAgICAgICAjIHNwYXRpYWwgZGF0YSB0b29scw0KbGlicmFyeShjZXJhbWljKSAgICAgICMgZG93bmxvYWQgb25saW5lIGltYWdlcnkgdGlsZXMNCmxpYnJhcnkoY29tcHN0YXRyKSAgICAjIHRvb2xzIGZvciBTVEwgY3JpbWUgZGF0YQ0KbGlicmFyeShyYXN0ZXIpICAgICAgICMgZ2VvZ3JhcGljIGRhdGEgYW5hbHlzaXMgJiBtb2RlbGluZw0KbGlicmFyeShtYXB2aWV3KQ0KDQojIG90aGVyIHBhY2thZ2VzDQpsaWJyYXJ5KGhlcmUpICAgICAgICAgIyBmaWxlIHBhdGggbWFuYWdlbWVudA0KbGlicmFyeShSQ29sb3JCcmV3ZXIpICMgY3ludGhpYSBicmV3ZXIgY29sb3IgcGFsZXR0ZXMNCmxpYnJhcnkodmlyaWRpcykgICAgICAjIGNvbG9yIHBhbGV0dGVzDQpsaWJyYXJ5KGdhdGV3YXkpICAgICAgIyBhYXRhIGZyb20gdGhlIENpdHkgb2YgU3QuIExvdWlzDQpgYGANCg0KIyMgVGlkeSBkYXRhDQoNCiMjIyBDcmVhdGUgYW4gSW5kZXgNCg0KYGBge3IgQ3JlYXRlIENyaW1lIEluZGV4fQ0KaSA8LSBjc19jcmVhdGVfaW5kZXgoKQ0KYGBgDQoNCiMjIyBHZXQgRGF0YSAtIDIwMTkNCg0KYGBge3IgUHVsbCAyMDE5IERhdGF9DQp1cGRhdGUgPC0gY3NfbGFzdF91cGRhdGUoKQ0KdXBkYXRlIDwtIHN0cnNwbGl0KHVwZGF0ZSwgIiAiKVtbMV1dDQpjX21vbnRoIDwtIHVwZGF0ZVtbMV1dDQpjX3llYXIgPC0gYXMubnVtZXJpYyh1cGRhdGVbWzJdXSkNCnllYXJMaXN0MTkgPC0gY3NfZ2V0X2RhdGEoeWVhciA9IGNfeWVhciwgaW5kZXggPSBpKQ0KYGBgDQoNCiMjIyBEb3dubG9hZCBDdXJyZW50IE1vbnRoDQoNCmBgYHtyIFZhbGlkYXRlIDIwMTkgRGF0YX0NCmNzX3ZhbGlkYXRlKHllYXJMaXN0MTksIHllYXIgPSAyMDE5KQ0KYGBgDQoNCmBgYHtyIFN0YW5kYXJkaXplIDIwMTkgRGF0YX0NCnRvdGFsQ3JpbWVzMTkgPC0gY3NfY29sbGFwc2UoeWVhckxpc3QxOSkNCmBgYA0KDQoNCmBgYHtyIFByaW50IEN1cnJlbnQgTW9udGh9DQpwcmludChjX21vbnRoKQ0KYGBgDQoNCg0KYGBge3IgRXh0cmFjdCBBdWd1c3QgMjAxOSBEYXRhfQ0KY3JpbWVzMTkgPC0gY3NfZXh0cmFjdF9tb250aCh5ZWFyTGlzdDE5LCBtb250aCA9ICJBdWd1c3QiKQ0KYGBgDQoNCiMjIyBDbGVhbiAmIENhdGVnb3JpemUgRGF0YSAtIDIwMTkNCg0KYGNzX2ZpbHRlcl9jb3VudGAgcmVtb3ZlcyBuZWdhdGl2ZSBjb3VudHMuIE5lZ2F0aXZlIGNvdW50cywgLTEsIGluIHRoZSBjb3VudCBjb2x1bW4gbWVhbnMgdGhhdCB0aGUgY3JpbWUsIG9yIGNoYXJnZSBpbiB0aGlzIHNwZWNpZmljIG9ic2VydmF0aW9uIGhhcyBlaXRoZXIgYmVlbiBkZWVtZWQgdW5mb3VuZGVkLCBvciB0aGUgY3JpbWUgaGFzIGJlZW4gdXAgY29kZWQuIFdlIGRvIG5vdCB3YW50IHRvIG1hcCB0aGlzIGRhdGEuIA0KDQpNYW55IG9mIHRoZSBhbmFseXNlcyB3ZSBjb25kdWN0IGluY2x1ZGUgY29tcGFyaXNvbnMgYmV0d2VlbiB2aW9sZW50ICYgbm9uLXZpb2xlbnQgY3JpbWUsIGNvbXBhcmlzb25zIG9uIHRoZSBhbW91bnQgb2YgY3JpbWVzIGhhcHBlbmluZyBpbiBlYWNoIGNyaW1lIGNhdGVvZ3kgb3ZlciB0aW1lLCBhbmQgaWYgY3JpbWVzIG9jY3VyIGR1cmluZyB0aGUgZGF5IG9yIGF0IG5pZ2h0LiBUaGUgZm9sbG93aW5nIGNvZGUgY2VhdGVzIHZhcmlhYmxlcyB0byBjb25kdWN0IHRoZXNlIGFuYWx5c2VzLiANCg0KYGNzX2NyaW1lX2NhdGAgY3JlYXRlcyBhIHZhcmlhYmxlIHdpdGggdGhlIG5hbWVzIG9mIHRoZSBjcmltZS4gDQoNCmBjc19jcmltZWAgY3JlYXRlcyBhIGxvZ2ljIHZhcmlhYmxlIGFuZCBjb2RlcyB2aW9sZW50IGNyaW1lcyBhcyBgVFJVRWAgYW5kIG5vbi12aW9sZW50IGNyaW1lcyBhcyBgRkFMU0VgDQoNCmBjc19wYXJzZV9kYXRlYCBjcmVhdGVzIHR3byBjb2x1bW5zIHNlcGFyYXRpbmcgdGhlIGBEYXRlIE9jY3VyYCB2YXJpYWJsZS4gVGhlIHR3byBjb2x1bXMgYXJlIGFzIGZvbGxvd3M6IG9uZSBjb250YWlucyB0aGUgZGF0ZSAtIG1vbnRoLCBkYXRlLCBhbmQgeWVhciwgYW5kIHRoZSBvdGhlciBjb250YWlucyB0aGUgaG91ciBhbmQgbWludXRlLiBUaGlzIGlzIHVzZWQgYmVjYXVzZSBjcmltZXMgY29kZWQgaW4gdGhlIG1vc3QgcmVjZW50IG1vbnRoLCBjYW4gY29udGFpbiBkYXRlcyB0aGF0IG9jY3VyZWQsIGluIHByZXZpb3VzIG1vbnRocyBvciB5ZWFycyAmIGluIHRoaXMgcmVwb3J0IHdlIG9ubHkgd2FudCB0byBtYXAgdGhlIGNyaW1lcyB0aGF0IG9jY3VyZWQgaW4gdGhlIHBhc3QgbW9udGguIA0KDQpgZmlsdGVyYCBpcyBhIGBkcGx5cmAgZnVuY3Rpb24gdGhhdCBmaWx0ZXJzIG91dCBhbnkgZGF0ZXMgdGhhdCBvY2N1ciBiZWZvcmUgdGhlIG91ciBzZWxlY3RlZCBkYXRlLCBhbmQgYWxzbyBmaWx0ZXJzIG91dCBjcmltZXMgdGhhdCBkaWQgbm90IGhhcHBlbiBpbiBlaXRoZXIgRGlzdHJpY3QgMiBvciBkaXN0cmljdCA1LiANCg0KYG11dGF0ZWAgYWRkcyBhIHZhcmlhYmxlIHRoYXQgY29kZXMgYW5kIGxhYmVscyB0aGUgZGF5cyBvZiB0aGUgd2VlayBmb3IgZWFjaCBjcmltZSB0aGF0IG9jY3VycmVkLCBhbmQgY3JlYXRlcyBhbm90aGVyIHRpbWUgb2YgZGF5IHZhcmlhYmxlIA0KDQpgYGB7ciBDcmVhdGVzIDIwMTkgQ2F0ZWdvcml6ZWQgVGlkeSBDcmltZSBGaWxlfQ0KdGlkeUNyaW1lczE5IDwtIGNyaW1lczE5ICU+JSANCiAgY3NfZmlsdGVyX2NvdW50KC4sIHZhciA9IGNvdW50KSAlPiUNCiAgY3NfZmlsdGVyX2NyaW1lKC4sIHZhciA9IGNyaW1lLCAicGFydCAxIikgJT4lDQogIGNzX2NyaW1lX2NhdCguLCB2YXIgPSBjcmltZSwgY3JpbWVDYXROdW0sICJudW1lcmljIikgJT4lDQogIGNzX2NyaW1lX2NhdCguLCB2YXIgPSBjcmltZSwgY3JpbWVDYXROYW1lLCAic3RyaW5nIikgJT4lDQogIGNzX2NyaW1lKC4sIHZhciA9IGNyaW1lLCB2aW9sZW50LCAidmlvbGVudCIpICU+JQ0KICBjc19jcmltZSguLCB2YXIgPSBjcmltZSwgcHJvcGVydHksICJwcm9wZXJ0eSIpICU+JQ0KICBjc19wYXJzZV9kYXRlKC4sIGRhdGVfb2NjdXIsIGRhdGVWYXIgPSBkYXRlT2NjLCB0aW1lVmFyID0gdGltZU9jYykgJT4lDQogIGZpbHRlcihkYXRlT2NjID49IGFzLkRhdGUoIjIwMTktMDgtMDEiKSkgJT4lDQogIGZpbHRlcihkaXN0cmljdCA9PSAyIHwgZGlzdHJpY3QgPT0gNSkgJT4lDQogIG11dGF0ZSh3ZWVrZGF5ID0gd2RheShkYXRlT2NjLCBsYWJlbCA9IFRSVUUpKSAlPiUNCiAgbXV0YXRlKHRvZCA9IHRpbWVPY2MpDQoNCnRpZHlDcmltZXMxOSRuZWlnaGJvcmhvb2QgPC0gYXMubnVtZXJpYyh0aWR5Q3JpbWVzMTkkbmVpZ2hib3Job29kKQ0KYGBgDQoNCmBzdHJwdGltZWAgYW5kIGBmb3JtYXRgIHRha2VzIHRoZSBuZXcgdGltZSB2YXJpYWJsZSBhbmQgZm9ybWF0cyBpdCB0byBhIGNoYXJhY3RlciBzbyB0aGF0IHdlIGNhbiBkZXRlcm1pbmUgaWYgdGhlIGNyaW1lIG9jY3VyZWQgYXQgZGF5IG9yIGF0IG5pZ2h0LCBhbmQgY3JlYXRlcyBhIHNlY29uZCBjb2RlZCB2YXJpYWJsZSB0aGF0IGxhYmVscyBlYWNoIG9ic2VydmF0aW9ucyBhcyBkYXkgb3IgbmlnaHQgYmFzZWQgb24gdGhlIG5ld2x5IGZvcm1hdGVkIHRpbWUgdmFyaWFibGUuIA0KDQpgc2VsZWN0YCBkcm9wcyB0aGUgdW5uZWVkZWQgdmFyaWFibGVzLiANCg0KYGNzX21pc3NpbmdfWFlgIGRldGVybWluZXMgd2hhdCBkYXRhIGRvZXMgbm90IGhhdmUgeCAmIHkgY29vcmRpbmF0ZXMsIGFuZCB0aGVyZWZvcmUgY2Fubm90IGJlIGFjY3VyYXRlbHkgbWFwcGVkLiANCg0KYGNzX3JlcGxhY2UwYCByZXBsYWNlcyBtaXNzaW5nIHggJiB5IGNvb3JkaW5hdGVzIHdpdGggYE5BYCwgYW5kIGRyb3BzIHRoZSBtaXNzaW5nIGRhdGEuIA0KDQpgYGB7ciBDbGVhbnMgMjAxOSBUaW1lIERhdGEgJiBNaXNzaW5nIFNwYXRpYWwgRGF0YX0NCnRpZHlDcmltZXMxOSR0b2QgPC0gc3RycHRpbWUodGlkeUNyaW1lczE5JHRvZCwgdHogPSAiQW1lcmljYS9DaGljYWdvIiwgIiVIOiVNIikNCnRpZHlDcmltZXMxOSR0b2QgPC0gZm9ybWF0KHRpZHlDcmltZXMxOSR0b2QsIGZvcm1hdCA9ICIlSCVNJVMiKQ0KDQp0aWR5Q3JpbWVzMTkgPC0gdGlkeUNyaW1lczE5ICU+JQ0KICBtdXRhdGUoLiwgZGF5TmlnaHQgPSBpZmVsc2UodG9kID49ICIxODAwMDAiICYgdG9kIDwgIjYwMDAwMCIsICJOaWdodCIsICJEYXkiKSkgJT4lIA0KICBkcGx5cjo6c2VsZWN0KC1kYXRlVGltZSwgLXRvZCwgLWZsYWdfY3JpbWUsIC1mbGFnX2FkbWluaXN0cmF0aXZlLCAtZmxhZ191bmZvdW5kZWQsIC1mbGFnX2NsZWFudXApDQoNCnRpZHlDcmltZXMxOSA8LSBjc19taXNzaW5nWFkodGlkeUNyaW1lczE5LCB2YXJYID0geF9jb29yZCwgdmFyWSA9IHlfY29vcmQsIG5ld1ZhciA9IG1pc3NpbmcpDQp0YWJsZSh0aWR5Q3JpbWVzMTkkbWlzc2luZykNCg0KdGlkeUNyaW1lczE5IDwtIHRpZHlDcmltZXMxOSAlPiUgDQogIGNzX3JlcGxhY2UwKC4sIHZhciA9IHhfY29vcmQpICU+JQ0KICBjc19yZXBsYWNlMCguLCB2YXIgPSB5X2Nvb3JkKSAlPiUgDQogIGZpbHRlciguLCBtaXNzaW5nID09IEZBTFNFKSANCmBgYA0KDQojIyMgR2V0IERhdGEgLSAyMDE4DQoNCmBgYHtyIERvd25sb2FkIDIwMTggRGF0YX0NCnllYXJMaXN0MTggPC0gY3NfZ2V0X2RhdGEoeWVhciA9IDIwMTgsIGluZGV4ID0gaSkNCmBgYA0KDQojIyMgRGF0YSBQcmVwZXJhdGlvbg0KDQpgYGB7ciBWYWxpZGF0ZSAyMDE4IERhdGF9DQpjc192YWxpZGF0ZSh5ZWFyTGlzdDE4LCB5ZWFyID0gMjAxOCkNCmBgYA0KDQojIyMgRG93bmxvYWQgTGFzdCBZZWFyJ3MgTW9udGgNCmBgYHtyIEV4dHJhY3QgTGFzdCBZZWFycyBDcmltZSBEYXRhIEZvciBDdXJyZW50IE1vbnRofQ0KdG90YWxDcmltZXMxOCA8LSBjc19jb2xsYXBzZSh5ZWFyTGlzdDE4KQ0KY3JpbWVzMTggPC0gY3NfZXh0cmFjdF9tb250aCh5ZWFyTGlzdDE4LCBtb250aCA9ICJBdWd1c3QiKQ0KYGBgDQoNCiMjIyBDbGVhbiAmIENhdGVnb3JpemUgRGF0YSAtIDIwMTgNCg0KYGBge3IgRmlsdGVyICYgQ2F0ZWdvcml6ZSAyMDE4IERhdGF9DQp0aWR5Q3JpbWVzMTggPC0gY3JpbWVzMTggJT4lIA0KICBjc19maWx0ZXJfY291bnQoLiwgdmFyID0gY291bnQpICU+JQ0KICBjc19maWx0ZXJfY3JpbWUoLiwgdmFyID0gY3JpbWUsICJwYXJ0IDEiKSAlPiUNCiAgY3NfY3JpbWVfY2F0KC4sIHZhciA9IGNyaW1lLCBjcmltZUNhdE51bSwgIm51bWVyaWMiKSAlPiUNCiAgY3NfY3JpbWVfY2F0KC4sIHZhciA9IGNyaW1lLCBjcmltZUNhdE5hbWUsICJzdHJpbmciKSAlPiUNCiAgY3NfY3JpbWUoLiwgdmFyID0gY3JpbWUsIHZpb2xlbnQsICJ2aW9sZW50IikgJT4lDQogIGNzX2NyaW1lKC4sIHZhciA9IGNyaW1lLCBwcm9wZXJ0eSwgInByb3BlcnR5IikgJT4lDQogIGNzX3BhcnNlX2RhdGUoLiwgZGF0ZV9vY2N1ciwgZGF0ZVZhciA9IGRhdGVPY2MsIHRpbWVWYXIgPSB0aW1lT2NjKSAlPiUNCiAgZmlsdGVyKGRhdGVPY2MgPj0gYXMuRGF0ZSgiMjAxOC0wOC0wMSIpICYgZGF0ZU9jYyA8PSBhcy5EYXRlKCIyMDE4LTA4LTMxIikpICU+JQ0KICBmaWx0ZXIoZGlzdHJpY3QgPT0gMiB8IGRpc3RyaWN0ID09IDUpICU+JQ0KICBtdXRhdGUod2Vla2RheSA9IHdkYXkoZGF0ZU9jYywgbGFiZWwgPSBUUlVFKSkgJT4lDQogIG11dGF0ZSh0b2QgPSB0aW1lT2NjKQ0KDQp0aWR5Q3JpbWVzMTgkbmVpZ2hib3Job29kIDwtIGFzLm51bWVyaWModGlkeUNyaW1lczE4JG5laWdoYm9yaG9vZCkNCg0KdGlkeUNyaW1lczE4JHRvZCA8LSBzdHJwdGltZSh0aWR5Q3JpbWVzMTgkdG9kLCB0eiA9ICJBbWVyaWNhL0NoaWNhZ28iLCAiJUg6JU0iKQ0KdGlkeUNyaW1lczE4JHRvZCA8LSBmb3JtYXQodGlkeUNyaW1lczE4JHRvZCwgZm9ybWF0ID0gIiVIJU0lUyIpDQoNCnRpZHlDcmltZXMxOCA8LSB0aWR5Q3JpbWVzMTggJT4lDQogIG11dGF0ZSguLCBkYXlOaWdodCA9IGlmZWxzZSh0b2QgPj0gIjE4MDAwMCIgJiB0b2QgPCAiNjAwMDAwIiwgIk5pZ2h0IiwgIkRheSIpKSAlPiUgDQogIGRwbHlyOjpzZWxlY3QoLWRhdGVUaW1lLCAtdG9kLCAtZmxhZ19jcmltZSwgLWZsYWdfYWRtaW5pc3RyYXRpdmUsIC1mbGFnX3VuZm91bmRlZCwgLWZsYWdfY2xlYW51cCkNCg0KdGlkeUNyaW1lczE4IDwtIGNzX21pc3NpbmdYWSh0aWR5Q3JpbWVzMTgsIHZhclggPSB4X2Nvb3JkLCB2YXJZID0geV9jb29yZCwgbmV3VmFyID0gbWlzc2luZykNCnRhYmxlKHRpZHlDcmltZXMxOCRtaXNzaW5nKQ0KDQp0aWR5Q3JpbWVzMTggPC0gdGlkeUNyaW1lczE4ICU+JSANCiAgY3NfcmVwbGFjZTAoLiwgdmFyID0geF9jb29yZCkgJT4lDQogIGNzX3JlcGxhY2UwKC4sIHZhciA9IHlfY29vcmQpICU+JSANCiAgZmlsdGVyKC4sIG1pc3NpbmcgPT0gRkFMU0UpDQpgYGANCg0KDQojIyMgQ29tYmluZSAyMDE4ICYgMjAxOSANCg0KYGBge3IgSm9pbiBQcmV2aW91cyBZZWFycyBDcmltZXN9DQphdWd1c3RDcmltZXMgPC0gcmJpbmQodGlkeUNyaW1lczE4LCB0aWR5Q3JpbWVzMTkpDQpgYGANCg0KIyMjIENyZWF0ZSBTcGF0aWFsIE9iamVjdHMNCg0KYGBge3IgQ3JlYXRlIFNGIG9iamVjdHMgZm9yIDIwMTggJiAyMDE5IENyaW1lc30NCmNyaW1lczE4X3NmIDwtIGNzX3Byb2plY3RYWSh0aWR5Q3JpbWVzMTgsIHZhclggPSB4X2Nvb3JkLCB2YXJZID0geV9jb29yZCwgY3JzID0gMTAyNjk2KQ0KY3JpbWVzMTlfc2YgPC0gY3NfcHJvamVjdFhZKHRpZHlDcmltZXMxOSwgdmFyWCA9IHhfY29vcmQsIHZhclkgPSB5X2Nvb3JkLCBjcnMgPSAxMDI2OTYpDQphdWd1c3RDcmltZXNfc2YgPC0gY3NfcHJvamVjdFhZKGF1Z3VzdENyaW1lcywgdmFyWCA9IHhfY29vcmQsIHZhclkgPSB5X2Nvb3JkLCBjcnMgPSAxMDI2OTYpDQpgYGANCg0KIyMjIFByZXAgZm9yIERhdGEgYnkgTmVpZ2hib3Job29kDQoNCmBgYHtyIE5laWdoYm9yaG9vZCBOdW1iZXIgTGlzdHN9DQpzYSA8LSBjKDM5LDI4LDM4LDUxLDUzLDU0LDU4LDQ2LDQ3LDQ4LDQ4KQ0KZHN0MiA8LSBjKDc6MTUsMjc6MjksIDM5OjQ1LDgxLDgyLDg3LDg4KQ0KZHN0NSA8LSBjKDM4LDQ2OjU4LDc4KQ0KYGBgDQoNCiMjIE1hcHBpbmcgDQoNCk9uZSB3YXkgd2Ugd29yayB0byBpbXByb3ZlIHRoZSBsZXZlbCBvZiBwaHlzaWNhbCAmIHBlcnNvbmFsIHNlY3VyaXR5IGlzIHRoZSBhbmFseXNpcyBhbmQgZGlzdHJpYnV0aW9uIG9mIGNyaW1lIGRhdGEgYW5kIHN0YXRpc3RpY3MuIFRoZSBvcmlnaW5hbCBzb3VyY2Ugb2YgdGhpcyBjcmltZSBkYXRhIGlzIDxodHRwOi8vc2xtcGQub3JnL2NyaW1lcmVwb3J0cy5zaHRtbD4uIFRoaXMgbm90ZWJvb2sgdGFrZXMgdGhlIGRhdGEgdGhhdCB3YXMgcHJldmlvdXNseSBjbGVhbmVkIGFuZCBtYXBzIHRoZSBkYXRhLiAgDQoNCiMjIExvYWQgU3BhdGlhbCBEYXRhIA0KDQojIyMgQ29vcmRpbmF0ZXMNCg0KYGBge3IgU2VydmljZSBBcmVhIE5laWdoYm9yaG9vZCBDb29yZGluYXRlc30NCnh5ZnBzZSA8LSBjKC05MC4yNjc5LCAtOTAuMjQyMywgMzguNjE3NiwgMzguNjMzNCkNCnh5Y3dlIDwtIGMoLTkwLjI3NTksIC05MC4yMzY4LCAzOC42Mjg2LCAzOC42NTUyKQ0KeHlib3QgPC0gYygtOTAuMjYxOSwgLTkwLjI0MDksIDM4LjYxNjUsIDM4LjYyOTYpDQp4eWRicCA8LSBjKC05MC4yODY5LCAtOTAuMjcyNiwgMzguNjQzMywgMzguNjU2NikNCnh5c2RiIDwtIGMoLTkwLjMwMjYsIC05MC4yODI3LCAzOC42NDU2LCAzOC42NTcxKQ0KeHl3ZSA8LSBjKC05MC4zMDIwLCAtOTAuMjcxMiwgMzguNjUxNywgMzguNjcxMCkNCnh5dnAgPC0gYygtOTAuMjgwMywgLTkwLjI3MTIsIDM4LjY1MTcsIDM4LjY2MjIpDQp4eWFjIDwtIGMoLTkwLjI3NDQsIC05MC4yNjA5LCAzOC42NTA1LCAzOC42NjYxKQ0KeHlmcCA8LSBjKC05MC4yNjQ4LCAtOTAuMjU0MywgMzguNjQ5MywgMzguNjY1NSkNCnh5bHAgPC0gYygtOTAuMjU4OCwgLTkwLjI0MzcsIDM4LjY0ODEsIDM4LjY2MjQpDQp4eXZkIDwtIGMoLTkwLjI1MjAsIC05MC4yMzA0LCAzOC42NDI2LCAzOC42NTg1KQ0KeHltYyA8LSBjKC05MC4yNjc4LCAtOTAuMjUxNSwgMzguNjMwNSwgMzguNjQxMSkNCnh5Y3R4IDwtIGMoLTkwLjI1ODEsIC05MC4yNDE5LCAzOC42Mjk5LCAzOC42Mzg2KQ0KeHlncnYgPC0gYygtOTAuMjY2MiwgLTkwLjI0NDAsIDM4LjYyMzgsIDM4LjYzMTgpDQp4eWRzdDIgPC0gYygtOTAuMzIwMywgLTkwLjIyOTcsIDM4LjU2MTMsIDM4LjY0OTMpDQp4eWRzdDUgPC0gYygtOTAuMzA4MCwgLTkwLjIxMzIsIDM4LjYyNzMsIDM4LjY5NjIpDQpgYGANCg0KDQojIyMgT3BlbiBTdHJlZXQgTWFwIGZyb20gTWFwYm94IC0gQmFzZW1hcCBUaWxlIEltYWdlcnkNCg0KYGBge3IgT2J0YWluIEJhc2VtYXAgVGlsZXMsIGluY2x1ZGU9RkFMU0V9DQpmcHNlX3RpbGVzIDwtIHJhc3Rlcjo6ZXh0ZW50KHh5ZnBzZSkgJT4lDQogIGNjX2xvY2F0aW9uKC4sIHR5cGUgPSAibWFwYm94LnN0cmVldHMiLCBtYXhfdGlsZXMgPSAxNSkNCg0KY3dlX3RpbGVzIDwtIHJhc3Rlcjo6ZXh0ZW50KHh5Y3dlKSAlPiUgDQogIGNjX2xvY2F0aW9uKC4sIHR5cGUgPSAibWFwYm94LnN0cmVldHMiLCBtYXhfdGlsZXMgPSAxNSkNCg0KYm90X3RpbGVzIDwtIHJhc3Rlcjo6ZXh0ZW50KHh5Ym90KSAlPiUNCiAgY2NfbG9jYXRpb24oLiwgdHlwZSA9ICJtYXBib3guc3RyZWV0cyIsIG1heF90aWxlcyA9IDE1KQ0KDQpkYnBfdGlsZXMgPC0gcmFzdGVyOjpleHRlbnQoeHlkYnApICU+JSANCiAgY2NfbG9jYXRpb24oLiwgdHlwZSA9ICJtYXBib3guc3RyZWV0cyIsIG1heF90aWxlcyA9IDE1KQ0KDQpzZGJfdGlsZXMgPC0gcmFzdGVyOjpleHRlbnQoeHlzZGIpICU+JQ0KICBjY19sb2NhdGlvbiguLCB0eXBlID0gIm1hcGJveC5zdHJlZXRzIiwgbWF4X3RpbGVzID0gMTUpDQoNCndlX3RpbGVzIDwtIHJhc3Rlcjo6ZXh0ZW50KHh5d2UpICU+JSANCiAgY2NfbG9jYXRpb24oLiwgdHlwZSA9ICJtYXBib3guc3RyZWV0cyIsIG1heF90aWxlcyA9IDE1KQ0KDQp2cF90aWxlcyA8LSByYXN0ZXI6OmV4dGVudCh4eXZwKSAlPiUNCiAgY2NfbG9jYXRpb24oLiwgdHlwZSA9ICJtYXBib3guc3RyZWV0cyIsIG1heF90aWxlcyA9IDE1KQ0KDQphY190aWxlcyA8LSByYXN0ZXI6OmV4dGVudCh4eWFjKSAlPiUgDQogIGNjX2xvY2F0aW9uKC4sIHR5cGUgPSAibWFwYm94LnN0cmVldHMiLCBtYXhfdGlsZXMgPSAxNSkNCg0KZnBfdGlsZXMgPC0gcmFzdGVyOjpleHRlbnQoeHlmcCkgJT4lIA0KICBjY19sb2NhdGlvbiguLCB0eXBlID0gIm1hcGJveC5zdHJlZXRzIiwgbWF4X3RpbGVzID0gMTUpDQoNCmxwX3RpbGVzIDwtIHJhc3Rlcjo6ZXh0ZW50KHh5bHApICU+JQ0KICBjY19sb2NhdGlvbiguLCB0eXBlID0gIm1hcGJveC5zdHJlZXRzIiwgbWF4X3RpbGVzID0gMTUpDQoNCnZkX3RpbGVzIDwtIHJhc3Rlcjo6ZXh0ZW50KHh5dmQpICU+JSANCiAgY2NfbG9jYXRpb24oLiwgdHlwZSA9ICJtYXBib3guc3RyZWV0cyIsIG1heF90aWxlcyA9IDE1KQ0KDQptY190aWxlcyA8LSByYXN0ZXI6OmV4dGVudCh4eW1jKSAlPiUgDQogIGNjX2xvY2F0aW9uKC4sIHR5cGUgPSAibWFwYm94LnN0cmVldHMiLCBtYXhfdGlsZXMgPSAxNSkNCg0KY3R4X3RpbGVzIDwtIHJhc3Rlcjo6ZXh0ZW50KHh5Y3R4KSAlPiUgDQogIGNjX2xvY2F0aW9uKC4sIHR5cGUgPSAibWFwYm94LnN0cmVldHMiLCBtYXhfdGlsZXMgPSAxNSkNCg0KZ3J2X3RpbGVzIDwtIHJhc3Rlcjo6ZXh0ZW50KHh5Z3J2KSAlPiUgDQogIGNjX2xvY2F0aW9uKC4sIHR5cGUgPSAibWFwYm94LnN0cmVldHMiLCBtYXhfdGlsZXMgPSAxNSkNCg0KZHN0Ml90aWxlcyA8LSByYXN0ZXI6OmV4dGVudCh4eWRzdDIpICU+JSANCiAgY2NfbG9jYXRpb24oLiwgdHlwZSA9ICJtYXBib3guc3RyZWV0cyIsIG1heF90aWxlcyA9IDE1KQ0KDQpkc3Q1X3RpbGVzIDwtIHJhc3Rlcjo6ZXh0ZW50KHh5ZHN0NSkgJT4lIA0KICBjY19sb2NhdGlvbiguLCB0eXBlID0gIm1hcGJveC5zdHJlZXRzIiwgbWF4X3RpbGVzID0gMTUpDQoNCnJtKHh5ZnBzZSwgeHljd2UsIHh5Ym90LCB4eWRicCwgeHlzZGIsIHh5d2UsIHh5dnAsIHh5YWMsIHh5ZnAsIHh5bHAsIHh5dmQsIHh5bWMsIHh5Y3R4LCB4eWdydiwgeHlkc3QyLCB4eWRzdDUpDQpgYGANCg0KIyMjIFNwYXRpYWwgRGF0YSBmcm9tIHRoZSBDaXR5IE9mIFN0LiBMb3Vpcw0KDQpgYGB7cn0NCm5ob29kc19zZiA8LSBnd19nZXRfZGF0YSgiTmVpZ2hib3Job29kcyIsICJzZiIpICU+JSANCiAgIHJlbmFtZShuZWlnaGJvcmhvb2QgPSBOSERfTlVNKQ0KDQpzYV9zZiA8LSBuaG9vZHNfc2YgJT4lIA0KICBmaWx0ZXIoLiwgbmVpZ2hib3Job29kICVpbiUgc2EpICU+JSANCg0KDQoNCmZwc2UgPC0gZmlsdGVyKG5ob29kc19zZiwgbmVpZ2hib3Job29kID09IDM5ICkNCmN3ZSA8LSBmaWx0ZXIobmhvb2RzX3NmLCBuZWlnaGJvcmhvb2QgPT0gMzggKQ0KYm90IDwtIGZpbHRlcihuaG9vZHNfc2YsIG5laWdoYm9yaG9vZCA9PSAyOCApDQpkYnAgPC0gZmlsdGVyKG5ob29kc19zZiwgbmVpZ2hib3Job29kID09IDQ3ICkNCnNkYiA8LSBmaWx0ZXIobmhvb2RzX3NmLCBuZWlnaGJvcmhvb2QgPT0gNDYgKQ0Kd2UgPC0gZmlsdGVyKG5ob29kc19zZiwgbmVpZ2hib3Job29kID09IDQ4ICkNCnZwIDwtIGZpbHRlcihuaG9vZHNfc2YsIG5laWdoYm9yaG9vZCA9PSA0OSApDQphYyA8LSBmaWx0ZXIobmhvb2RzX3NmLCBuZWlnaGJvcmhvb2QgPT0gNTEgKQ0KZnAgPC0gZmlsdGVyKG5ob29kc19zZiwgbmVpZ2hib3Job29kID09IDUzICkNCmxwIDwtIGZpbHRlcihuaG9vZHNfc2YsIG5laWdoYm9yaG9vZCA9PSA1NCApDQp2ZCA8LSBmaWx0ZXIobmhvb2RzX3NmLCBuZWlnaGJvcmhvb2QgPT0gNTggKQ0KYGBgDQojIyMgTG9hZCBFeHRlcm5hbCBEYXRhDQoNCiMjIyMgUG9wdWxhdGlvbiBEYXRhIA0KDQpgYGB7cn0NCmxvYWQoaGVyZSgiZGF0YS9uYmhkX3BvcDEwLnJkYSIpKQ0KYGBgDQoNCg0KIyMjIyBTcGF0aWFsIA0KDQpgYGB7ciBsb2FkIHNoYXBlZmlsZXMsIGluY2x1ZGU9RkFMU0V9DQpzdF9yZWFkKGhlcmUoImRhdGEiLCAiZXh0ZXJuYWwiLCAibWVkLWNhbXB1cyIsICJtZWRjYW1wdXMuc2hwIikpICU+JQ0KICBzdF90cmFuc2Zvcm0oY3JzID0gMTAyNjk2KSAtPiBtZWRfY2FtcHVzDQoNCnN0X3JlYWQoaGVyZSgiZGF0YSIsICJleHRlcm5hbCIsICJjb3J0ZXgtYm91bmRhcnkiLCAiQ09SVEVYIEJPVU5EQVJZLnNocCIpKSAlPiUNCiAgc3RfdHJhbnNmb3JtKGNycyA9IDEwMjY5NikgLT4gY29ydGV4DQoNCnN0X3JlYWQoaGVyZSgiZGF0YSIsICJleHRlcm5hbCIsICJncm92ZS1jaWQiLCAiZ3JvdmVjaWQuc2hwIikpICU+JQ0KICBzdF90cmFuc2Zvcm0oY3JzID0gMTAyNjk2KSAtPiBncm92ZV9jaWQNCmBgYA0KDQojIyMgQ29tYmluZSBQb3B1bGF0aW9uICYgTmVpZ2hib3Job29kIFNwYXRpYWwgRGF0YSBieSBQb2xpY2UgRGlzdHJpY3QNCg0KIyMjIyBPZ2FuaXplICYgRmlsdGVyIENyaW1lIERhdGEgYnkgTmVpZ2hib3Job29kIA0KDQpgYGB7ciBDcmltZSBSYXRlcyAtIERpc3RyaWN0IDJ9DQpkc3RfMiA8LSB0aWR5Q3JpbWVzMTkgJT4lIA0KICBmaWx0ZXIoLiwgbmVpZ2hib3Job29kICVpbiUgZHN0MikgJT4lIA0KICBncm91cF9ieSguLCBuZWlnaGJvcmhvb2QpICU+JQ0KICBjb3VudCgpICU+JSANCiAgcmVuYW1lKGNyaW1lVG90YWwgPSBuKSAlPiUNCiAgbGVmdF9qb2luKG5iaGRfcG9wMTAsIGJ5ID0gIm5laWdoYm9yaG9vZCIpICU+JSANCiAgbXV0YXRlKC4sIGNyaW1lUmF0ZSA9IChjcmltZVRvdGFsL3BvcDEwKSoxMDAwKSAlPiUgDQogIGRyb3BfbmEoKQ0KYGBgDQoNCmBgYHtyIENyaW1lIFJhdGVzIC0gRGlzdHJpY3QgNX0NCmRzdF81IDwtIHRpZHlDcmltZXMxOSAlPiUgDQogIGZpbHRlciguLCBuZWlnaGJvcmhvb2QgJWluJSBkc3Q1KSAlPiUgDQogIGdyb3VwX2J5KC4sIG5laWdoYm9yaG9vZCkgJT4lDQogIGNvdW50KCkgJT4lIA0KICByZW5hbWUoY3JpbWVUb3RhbCA9IG4pICU+JQ0KICBsZWZ0X2pvaW4obmJoZF9wb3AxMCwgYnkgPSAibmVpZ2hib3Job29kIikgJT4lIA0KICBtdXRhdGUoLiwgY3JpbWVSYXRlID0gKGNyaW1lVG90YWwvcG9wMTApKjEwMDApICU+JSANCiAgZHJvcF9uYSgpDQpgYGANCg0KYGBge3IgSm9pbiBSYXRlcyAmIE5laWdoYm9yaG9vZHMgLSBEaXN0cmljdCAyfQ0KZHN0XzJfcG9wIDwtIGxlZnRfam9pbihuaG9vZHNfc2YsIGRzdF8yLCBieSA9ICJuZWlnaGJvcmhvb2QiKSAlPiUgDQogIHN0X3RyYW5zZm9ybShjcnMgPSAxMDI2OTYpICU+JQ0KICBkcm9wX25hKCkgJT4lIA0KICBzdWJzZXQoLiwgbmVpZ2hib3Job29kICE9IDg4KQ0KYGBgDQoNCmBgYHtyIEpvaW4gUmF0ZXMgJiBOZWlnaGJvcmhvb2RzIC0gRGlzdHJpY3QgNX0NCmRzdF81X3BvcCA8LSBsZWZ0X2pvaW4obmhvb2RzX3NmLCBkc3RfNSwgYnkgPSAibmVpZ2hib3Job29kIikgJT4lIA0KICBzdF90cmFuc2Zvcm0oY3JzID0gMTAyNjk2KSAlPiUNCiAgZHJvcF9uYSgpDQpgYGANCg0KDQojIyMgRlBTRSwgQk9ULCBDV0UsIE1DIA0KDQojIyMjIE1hcCBDcmVhdGlvbg0KDQojIyMjIyBGUFNFDQoNCmBgYHtyIEZQU0UgVG90YWwgQ3JpbWV9DQpmcHNlX3RvdGFsX3RtIDwtIHRtX3NoYXBlKGZwc2VfdGlsZXMpICsNCiAgdG1fcmdiKCkgKw0KICBuaG9vZHNfc2YgJT4lDQogIGZpbHRlciguLCBuZWlnaGJvcmhvb2QgPT0gMzkpICU+JSANCiAgdG1fc2hhcGUoKSArDQogICAgdG1fZmlsbChjb2wgPSAiIzllY2FlMSIsIA0KICAgICAgICAgICAgYWxwaGEgPSAuNSkgKw0KICAgIHRtX2JvcmRlcnMoY29sID0gImJsYWNrIiwgDQogICAgICAgICAgICAgICBsd2QgPSAyLCANCiAgICAgICAgICAgICAgIGx0eSA9ICJkYXNoZWQiKSArDQogIGZpbHRlcihjcmltZXMxOV9zZiwgDQogICAgICAgICBuZWlnaGJvcmhvb2QgPT0gMzkpICU+JQ0KICB0bV9zaGFwZSgpICsNCiAgICB0bV9idWJibGVzKHNpemUgPSAuMjUsIA0KICAgICAgICAgICAgICAgY29sID0gImNyaW1lQ2F0TmFtZSIsIA0KICAgICAgICAgICAgICAgcGFsZXR0ZSA9ICJTZXQxIiwgDQogICAgICAgICAgICAgICB0aXRsZS5jb2wgPSAiUGFydCAxIENyaW1lcyIpICsNCiAgdG1fY3JlZGl0cygiwqkgTWFwYm94LCDCqSBPcGVuU3RyZWV0TWFwIiwgcG9zaXRpb24gPSBjKCJsZWZ0IiwgIkJPVFRPTSIpKSArDQogIHRtX2xheW91dCgNCiAgICBtYWluLnRpdGxlID0gIkZQU0UgVG90YWwgQ3JpbWUgLSBBdWd1c3QgMjAxOSIsDQogICAgZnJhbWUgPSBGQUxTRSwNCiAgICBsZWdlbmQuYmcuY29sb3IgPSAid2hpdGUiLCANCiAgICBsZWdlbmQuZnJhbWU9VFJVRSwNCiAgICBsZWdlbmQub3V0c2lkZSA9IFRSVUUsDQogICAgbGVnZW5kLnBvc2l0aW9uID0gYygicmlnaHQiLCAiYm90dG9tIikpIA0KDQpmcHNlX3RvdGFsX3RtDQpgYGAgDQoNCg0KYGBge3IgRlBTRSBEYXkgJiBOaWdodH0NCmZwc2VfZG5fdG0gPC0gdG1fc2hhcGUoZnBzZV90aWxlcykgKw0KICB0bV9yZ2IoKSArDQogIG5ob29kc19zZiAlPiUNCiAgZmlsdGVyKC4sIG5laWdoYm9yaG9vZCA9PSAzOSkgJT4lIA0KICB0bV9zaGFwZSgpICsNCiAgICB0bV9maWxsKGNvbCA9ICIjOWVjYWUxIiwgDQogICAgICAgICAgICBhbHBoYSA9IC41KSArDQogICAgdG1fYm9yZGVycyhjb2wgPSAiYmxhY2siLCANCiAgICAgICAgICAgICAgIGx3ZCA9IDIsIA0KICAgICAgICAgICAgICAgbHR5ID0gImRhc2hlZCIpICsNCiAgZmlsdGVyKGNyaW1lczE5X3NmLCANCiAgICAgICAgIG5laWdoYm9yaG9vZCA9PSAzOSkgJT4lDQogIHRtX3NoYXBlKCkgKw0KICAgIHRtX2J1YmJsZXMoc2l6ZSA9IC4yNSwgDQogICAgICAgICAgICAgICBjb2wgPSAiZGF5TmlnaHQiLCANCiAgICAgICAgICAgICAgIHBhbGV0dGUgPSAiLVJkQnUiLCANCiAgICAgICAgICAgICAgIHRpdGxlLmNvbCA9ICJUaW1lIG9mIENyaW1lcyIpICsNCiAgdG1fY3JlZGl0cygiwqkgTWFwYm94LCDCqSBPcGVuU3RyZWV0TWFwIiwgcG9zaXRpb24gPSBjKCJsZWZ0IiwgIkJPVFRPTSIpKSArDQogIHRtX2xheW91dCgNCiAgICBtYWluLnRpdGxlID0gIkZQU0UgVGltZSBvZiBDcmltZXMgLSBBdWd1c3QgMjAxOSIsDQogICAgZnJhbWUgPSBGQUxTRSwNCiAgICBsZWdlbmQuYmcuY29sb3IgPSAid2hpdGUiLCANCiAgICBsZWdlbmQuZnJhbWU9VFJVRSwNCiAgICBsZWdlbmQub3V0c2lkZSA9IFRSVUUsDQogICAgbGVnZW5kLnBvc2l0aW9uID0gYygicmlnaHQiLCAiYm90dG9tIikpIA0KDQpmcHNlX2RuX3RtDQpgYGANCg0KYGBge3IgRlBTRSBDcmltZXMgQWdhaW5zdCBQZXJzb25zfQ0KZnBzZV92bG50X3RtIDwtIHRtX3NoYXBlKGZwc2VfdGlsZXMpICsNCiAgdG1fcmdiKCkgKw0KICBuaG9vZHNfc2YgJT4lDQogIGZpbHRlciguLCBuZWlnaGJvcmhvb2QgPT0gMzkpICU+JSANCiAgdG1fc2hhcGUoKSArDQogICAgdG1fZmlsbChjb2wgPSAiIzllY2FlMSIsIA0KICAgICAgICAgICAgYWxwaGEgPSAuNSkgKw0KICAgIHRtX2JvcmRlcnMoY29sID0gImJsYWNrIiwgDQogICAgICAgICAgICAgICBsd2QgPSAyLCANCiAgICAgICAgICAgICAgIGx0eSA9ICJkYXNoZWQiKSArDQogIGZpbHRlcihjcmltZXMxOV9zZiwgDQogICAgICAgICBuZWlnaGJvcmhvb2QgPT0gMzkpICU+JQ0KICB0bV9zaGFwZSgpICsNCiAgICB0bV9idWJibGVzKHNpemUgPSAuMjUsIA0KICAgICAgICAgICAgICAgY29sID0gInZpb2xlbnQiLCANCiAgICAgICAgICAgICAgIHBhbGV0dGUgPSAiUmVkcyIsIA0KICAgICAgICAgICAgICAgdGl0bGUuY29sID0gIlZpb2xlbnQiKSArDQogIHRtX2NyZWRpdHMoIsKpIE1hcGJveCwgwqkgT3BlblN0cmVldE1hcCIsIHBvc2l0aW9uID0gYygibGVmdCIsICJCT1RUT00iKSkgKw0KICB0bV9sYXlvdXQoDQogICAgbWFpbi50aXRsZSA9ICJGUFNFIFZpb2xlbnQgQ3JpbWUgLSBBdWd1c3QgMjAxOSIsDQogICAgZnJhbWUgPSBGQUxTRSwNCiAgICBsZWdlbmQuYmcuY29sb3IgPSAid2hpdGUiLCANCiAgICBsZWdlbmQuZnJhbWU9VFJVRSwNCiAgICBsZWdlbmQub3V0c2lkZSA9IFRSVUUsDQogICAgbGVnZW5kLnBvc2l0aW9uID0gYygicmlnaHQiLCAiYm90dG9tIikpIA0KDQpmcHNlX3ZsbnRfdG0NCmBgYA0KYGBge3IgRlBTRSBEZW5zaXR5IE1hcCBTRn0NCmNyaW1lczE5X3NmICU+JQ0KICBmaWx0ZXIobmVpZ2hib3Job29kID09IDM5KSAlPiUNCiAgc21vb3RoX21hcCguLCBiYW5kd2lkdGggPSAwLjUsIHN0eWxlID0gInByZXR0eSIsDQogIGNvdmVyID0gZnBzZSkgLT4gZnBzZV9kZW5zaXRpZXMNCmBgYA0KDQoNCmBgYHtyIEZQU0UgRGVuc2l0eSBNYXAgT3V0cHV0fQ0KZnBzZV9kZW5fdG0gPC0gdG1fc2hhcGUoZnBzZV90aWxlcykgKw0KICB0bV9yZ2IoKSArDQogIG5ob29kc19zZiAlPiUNCiAgZmlsdGVyKC4sIG5laWdoYm9yaG9vZCA9PSAzOSkgJT4lIA0KICB0bV9zaGFwZSgpICsNCiAgICB0bV9maWxsKGNvbCA9IE5BLCANCiAgICAgICAgICAgIGFscGhhID0gLjUpICsNCiAgICB0bV9ib3JkZXJzKGNvbCA9ICJibGFjayIsIA0KICAgICAgICAgICAgICAgbHdkID0gMiwgDQogICAgICAgICAgICAgICBsdHkgPSAiZGFzaGVkIikgKw0KICB0bV9zaGFwZShmcHNlX2RlbnNpdGllcyRwb2x5Z29ucykgKw0KICB0bV9maWxsKGNvbCA9ICJsZXZlbCIsIHBhbGV0dGUgPSAiQnVQdSIsIGFscGhhID0gLjYwLCANCiAgICB0aXRsZSA9IGV4cHJlc3Npb24oIkNyaW1lcyBwZXIgIiAqIGttXjIpKSArDQogIHRtX2NyZWRpdHMoIsKpIE1hcGJveCwgwqkgT3BlblN0cmVldE1hcCIsIHBvc2l0aW9uID0gYygibGVmdCIsICJCT1RUT00iKSkgKw0KICB0bV9sYXlvdXQoDQogICAgbWFpbi50aXRsZSA9ICJGUFNFIENyaW1lIERlbnNpdHkgLSBBdWd1c3QgMjAxOSIsDQogICAgZnJhbWUgPSBGQUxTRSwNCiAgICBsZWdlbmQuYmcuY29sb3IgPSAid2hpdGUiLCANCiAgICBsZWdlbmQuZnJhbWU9VFJVRSwNCiAgICBsZWdlbmQub3V0c2lkZSA9IFRSVUUsDQogICAgbGVnZW5kLnBvc2l0aW9uID0gYygicmlnaHQiLCAiYm90dG9tIikpIA0KDQpmcHNlX2Rlbl90bQ0KYGBgDQojIyMjIyMgR3JvdmUgQ0lEIA0KDQpgYGB7ciBHcm92ZSBDSUQgVG90YWwgQ3JpbWV9DQpncm92ZV9jcmltZXMgPC0gc3RfaW50ZXJzZWN0aW9uKGNyaW1lczE5X3NmLCBncm92ZV9jaWQpDQoNCmZwc2VfZ3JvdmVfdG0gPC0gdG1fc2hhcGUoZ3J2X3RpbGVzKSArDQogIHRtX3JnYigpICsNCiAgbmhvb2RzX3NmICU+JQ0KICBmaWx0ZXIoLiwgbmVpZ2hib3Job29kID09IDM5KSAlPiUgDQogIHRtX3NoYXBlKCkgKw0KICAgIHRtX2JvcmRlcnMoY29sID0gImJsYWNrIiwgDQogICAgICAgICAgICAgICBsd2QgPSAyLCANCiAgICAgICAgICAgICAgIGx0eSA9ICJkYXNoZWQiKSArDQogIHRtX3NoYXBlKGdyb3ZlX2NpZCkgKw0KICAgIHRtX2ZpbGwoY29sID0gIiM5ZWNhZTEiLCANCiAgICAgICAgICAgIGFscGhhID0gLjUpICsNCiAgICB0bV9ib3JkZXJzKGNvbCA9ICJibGFjayIsIA0KICAgICAgICAgICAgICAgbHdkID0gMSwgDQogICAgICAgICAgICAgICBsdHkgPSAic29saWQiKSArDQogIHRtX3NoYXBlKGdyb3ZlX2NyaW1lcykgKw0KICAgIHRtX2J1YmJsZXMoc2l6ZSA9IC4yNSwgDQogICAgICAgICAgICAgICBjb2wgPSAiY3JpbWVDYXROYW1lIiwgDQogICAgICAgICAgICAgICBwYWxldHRlID0gIlNldDEiLCANCiAgICAgICAgICAgICAgIHRpdGxlLmNvbCA9ICJQYXJ0IDEgQ3JpbWVzIikgKw0KICB0bV9jcmVkaXRzKCLCqSBNYXBib3gsIMKpIE9wZW5TdHJlZXRNYXAiLCBwb3NpdGlvbiA9IGMoImxlZnQiLCAiQk9UVE9NIikpICsNCiAgdG1fbGF5b3V0KA0KICAgIG1haW4udGl0bGUgPSAiR3JvdmUgQ0lEIFRvdGFsIENyaW1lIC0gQXVndXN0IDIwMTkiLA0KICAgIGZyYW1lID0gRkFMU0UsDQogICAgbGVnZW5kLmJnLmNvbG9yID0gIndoaXRlIiwgDQogICAgbGVnZW5kLmZyYW1lPVRSVUUsDQogICAgbGVnZW5kLm91dHNpZGUgPSBUUlVFLA0KICAgIGxlZ2VuZC5wb3NpdGlvbiA9IGMoInJpZ2h0IiwgImJvdHRvbSIpKSANCg0KZnBzZV9ncm92ZV90bQ0KYGBgDQoNCiMjIyMjIENXRQ0KDQoNCmBgYHtyIENXRSBUb3RhbCBDcmltZX0NCmN3ZV90b3RhbF90bSA8LSB0bV9zaGFwZShjd2VfdGlsZXMpICsNCiAgdG1fcmdiKCkgKw0KICBuaG9vZHNfc2YgJT4lDQogIGZpbHRlciguLCBuZWlnaGJvcmhvb2QgPT0gMzgpICU+JSANCiAgdG1fc2hhcGUoKSArDQogICAgdG1fZmlsbChjb2wgPSAiIzllY2FlMSIsIA0KICAgICAgICAgICAgYWxwaGEgPSAuNSkgKw0KICAgIHRtX2JvcmRlcnMoY29sID0gImJsYWNrIiwgDQogICAgICAgICAgICAgICBsd2QgPSAyLCANCiAgICAgICAgICAgICAgIGx0eSA9ICJkYXNoZWQiKSArDQogIGZpbHRlcihjcmltZXMxOV9zZiwgDQogICAgICAgICBuZWlnaGJvcmhvb2QgPT0gMzgpICU+JQ0KICB0bV9zaGFwZSgpICsNCiAgICB0bV9idWJibGVzKHNpemUgPSAuMjUsIA0KICAgICAgICAgICAgICAgY29sID0gImNyaW1lQ2F0TmFtZSIsIA0KICAgICAgICAgICAgICAgcGFsZXR0ZSA9ICJTZXQxIiwgDQogICAgICAgICAgICAgICB0aXRsZS5jb2wgPSAiUGFydCAxIENyaW1lcyIpICsNCiAgdG1fY3JlZGl0cygiwqkgTWFwYm94LCDCqSBPcGVuU3RyZWV0TWFwIiwgcG9zaXRpb24gPSBjKCJsZWZ0IiwgIkJPVFRPTSIpKSArDQogIHRtX2xheW91dCgNCiAgICBtYWluLnRpdGxlID0gIkNXRSBUb3RhbCBDcmltZSAtIEF1Z3VzdCAyMDE5IiwNCiAgICBmcmFtZSA9IEZBTFNFLA0KICAgIGxlZ2VuZC5iZy5jb2xvciA9ICJ3aGl0ZSIsIA0KICAgIGxlZ2VuZC5mcmFtZT1UUlVFLA0KICAgIGxlZ2VuZC5vdXRzaWRlID0gVFJVRSwNCiAgICBsZWdlbmQucG9zaXRpb24gPSBjKCJyaWdodCIsICJib3R0b20iKSkgDQoNCmN3ZV90b3RhbF90bQ0KYGBgIA0KDQoNCmBgYHtyIGN3ZSBEYXkgJiBOaWdodH0NCmN3ZV9kbl90bSA8LSB0bV9zaGFwZShjd2VfdGlsZXMpICsNCiAgdG1fcmdiKCkgKw0KICBuaG9vZHNfc2YgJT4lDQogIGZpbHRlciguLCBuZWlnaGJvcmhvb2QgPT0gMzgpICU+JSANCiAgdG1fc2hhcGUoKSArDQogICAgdG1fZmlsbChjb2wgPSAiIzllY2FlMSIsIA0KICAgICAgICAgICAgYWxwaGEgPSAuNSkgKw0KICAgIHRtX2JvcmRlcnMoY29sID0gImJsYWNrIiwgDQogICAgICAgICAgICAgICBsd2QgPSAyLCANCiAgICAgICAgICAgICAgIGx0eSA9ICJkYXNoZWQiKSArDQogIGZpbHRlcihjcmltZXMxOV9zZiwgDQogICAgICAgICBuZWlnaGJvcmhvb2QgPT0gMzgpICU+JQ0KICB0bV9zaGFwZSgpICsNCiAgICB0bV9idWJibGVzKHNpemUgPSAuMjUsIA0KICAgICAgICAgICAgICAgY29sID0gImRheU5pZ2h0IiwgDQogICAgICAgICAgICAgICBwYWxldHRlID0gIi1SZEJ1IiwgDQogICAgICAgICAgICAgICB0aXRsZS5jb2wgPSAiVGltZSBvZiBDcmltZXMiKSArDQogIHRtX2NyZWRpdHMoIsKpIE1hcGJveCwgwqkgT3BlblN0cmVldE1hcCIsIHBvc2l0aW9uID0gYygibGVmdCIsICJCT1RUT00iKSkgKw0KICB0bV9sYXlvdXQoDQogICAgbWFpbi50aXRsZSA9ICJDV0UgVG90YWwgQ3JpbWUgLSBBdWd1c3QgMjAxOSIsDQogICAgZnJhbWUgPSBGQUxTRSwNCiAgICBsZWdlbmQuYmcuY29sb3IgPSAid2hpdGUiLCANCiAgICBsZWdlbmQuZnJhbWU9VFJVRSwNCiAgICBsZWdlbmQub3V0c2lkZSA9IFRSVUUsDQogICAgbGVnZW5kLnBvc2l0aW9uID0gYygicmlnaHQiLCAiYm90dG9tIikpIA0KDQpjd2VfZG5fdG0NCmBgYA0KDQpgYGB7ciBDV0UgQ3JpbWVzIEFnYWluc3QgUGVyc29uc30NCmN3ZV92bG50X3RtIDwtIHRtX3NoYXBlKGN3ZV90aWxlcykgKw0KICB0bV9yZ2IoKSArDQogIG5ob29kc19zZiAlPiUNCiAgZmlsdGVyKC4sIG5laWdoYm9yaG9vZCA9PSAzOCkgJT4lIA0KICB0bV9zaGFwZSgpICsNCiAgICB0bV9maWxsKGNvbCA9ICIjOWVjYWUxIiwgDQogICAgICAgICAgICBhbHBoYSA9IC41KSArDQogICAgdG1fYm9yZGVycyhjb2wgPSAiYmxhY2siLCANCiAgICAgICAgICAgICAgIGx3ZCA9IDIsIA0KICAgICAgICAgICAgICAgbHR5ID0gImRhc2hlZCIpICsNCiAgZmlsdGVyKGNyaW1lczE5X3NmLCANCiAgICAgICAgIG5laWdoYm9yaG9vZCA9PSAzOCkgJT4lDQogIHRtX3NoYXBlKCkgKw0KICAgIHRtX2J1YmJsZXMoc2l6ZSA9IC4yNSwgDQogICAgICAgICAgICAgICBjb2wgPSAidmlvbGVudCIsIA0KICAgICAgICAgICAgICAgcGFsZXR0ZSA9ICJSZWRzIiwgDQogICAgICAgICAgICAgICB0aXRsZS5jb2wgPSAiVmlvbGVudCIpICsNCiAgdG1fY3JlZGl0cygiwqkgTWFwYm94LCDCqSBPcGVuU3RyZWV0TWFwIiwgcG9zaXRpb24gPSBjKCJsZWZ0IiwgIkJPVFRPTSIpKSArDQogIHRtX2xheW91dCgNCiAgICBtYWluLnRpdGxlID0gIkNXRSBUaW1lIG9mIENyaW1lcyAtIEF1Z3VzdCAyMDE5IiwNCiAgICBmcmFtZSA9IEZBTFNFLA0KICAgIGxlZ2VuZC5iZy5jb2xvciA9ICJ3aGl0ZSIsIA0KICAgIGxlZ2VuZC5mcmFtZT1UUlVFLA0KICAgIGxlZ2VuZC5vdXRzaWRlID0gVFJVRSwNCiAgICBsZWdlbmQucG9zaXRpb24gPSBjKCJyaWdodCIsICJib3R0b20iKSkgDQoNCmN3ZV92bG50X3RtDQpgYGANCg0KYGBge3IgQ1dFIERlbnNpdHkgTWFwIFNGfQ0KY3dlX2RlbnNpdGllcyA8LSBjcmltZXMxOV9zZiAlPiUNCiAgZmlsdGVyKG5laWdoYm9yaG9vZCA9PSAzOCkgJT4lDQogIHNtb290aF9tYXAoLiwgYmFuZHdpZHRoID0gMC41LCBzdHlsZSA9ICJwcmV0dHkiLA0KICBjb3ZlciA9IGN3ZSkNCmBgYA0KDQoNCmBgYHtyIENXRSBEZW5zaXR5IE1hcCBPdXRwdXR9DQpjd2VfZGVuX3RtIDwtIHRtX3NoYXBlKGN3ZV90aWxlcykgKw0KICB0bV9yZ2IoKSArDQogIG5ob29kc19zZiAlPiUNCiAgZmlsdGVyKC4sIG5laWdoYm9yaG9vZCA9PSAzOCkgJT4lIA0KICB0bV9zaGFwZSgpICsNCiAgICB0bV9maWxsKGNvbCA9IE5BLCANCiAgICAgICAgICAgIGFscGhhID0gLjUpICsNCiAgICB0bV9ib3JkZXJzKGNvbCA9ICJibGFjayIsIA0KICAgICAgICAgICAgICAgbHdkID0gMiwgDQogICAgICAgICAgICAgICBsdHkgPSAiZGFzaGVkIikgKw0KICB0bV9zaGFwZShjd2VfZGVuc2l0aWVzJHBvbHlnb25zKSArDQogIHRtX2ZpbGwoY29sID0gImxldmVsIiwgcGFsZXR0ZSA9ICJCdVB1IiwgYWxwaGEgPSAuNjAsIA0KICAgIHRpdGxlID0gZXhwcmVzc2lvbigiQ3JpbWVzIHBlciAiICoga21eMikpICsNCiAgdG1fY3JlZGl0cygiwqkgTWFwYm94LCDCqSBPcGVuU3RyZWV0TWFwIiwgcG9zaXRpb24gPSBjKCJsZWZ0IiwgIkJPVFRPTSIpKSArDQogIHRtX2xheW91dCgNCiAgICBtYWluLnRpdGxlID0gIkNXRSBDcmltZSBEZW5zaXR5LSBBdWd1c3QgMjAxOSIsDQogICAgZnJhbWUgPSBGQUxTRSwNCiAgICBsZWdlbmQuYmcuY29sb3IgPSAid2hpdGUiLCANCiAgICBsZWdlbmQuZnJhbWU9VFJVRSwNCiAgICBsZWdlbmQub3V0c2lkZSA9IFRSVUUsDQogICAgbGVnZW5kLnBvc2l0aW9uID0gYygicmlnaHQiLCAiYm90dG9tIikpIA0KDQpjd2VfZGVuX3RtDQpgYGANCiMjIyMjIyBNZWRpY2FsIENhbXB1cw0KDQpgYGB7ciBNZWRpY2FsIENhbXB1cyBUb3RhbCBDcmltZX0NCm1jX2NyaW1lcyA8LSBzdF9pbnRlcnNlY3Rpb24oY3JpbWVzMTlfc2YsIG1lZF9jYW1wdXMpDQoNCmN3ZV9tY190bSA8LSB0bV9zaGFwZShtY190aWxlcykgKw0KICB0bV9yZ2IoKSArDQogIG5ob29kc19zZiAlPiUNCiAgZmlsdGVyKC4sIG5laWdoYm9yaG9vZCA9PSAzOCkgJT4lIA0KICB0bV9zaGFwZSgpICsNCiAgICB0bV9ib3JkZXJzKGNvbCA9ICJibGFjayIsIA0KICAgICAgICAgICAgICAgbHdkID0gMiwgDQogICAgICAgICAgICAgICBsdHkgPSAiZGFzaGVkIikgKw0KICB0bV9zaGFwZShtZWRfY2FtcHVzKSArDQogICAgdG1fZmlsbChjb2wgPSAiIzllY2FlMSIsIA0KICAgICAgICAgICAgYWxwaGEgPSAuNSkgKw0KICAgIHRtX2JvcmRlcnMoY29sID0gImJsYWNrIiwgDQogICAgICAgICAgICAgICBsd2QgPSAxLCANCiAgICAgICAgICAgICAgIGx0eSA9ICJzb2xpZCIpICsNCiAgdG1fc2hhcGUobWNfY3JpbWVzKSArDQogICAgdG1fYnViYmxlcyhzaXplID0gLjI1LCANCiAgICAgICAgICAgICAgIGNvbCA9ICJjcmltZUNhdE5hbWUiLCANCiAgICAgICAgICAgICAgIHBhbGV0dGUgPSAiU2V0MSIsIA0KICAgICAgICAgICAgICAgdGl0bGUuY29sID0gIlBhcnQgMSBDcmltZXMiKSArDQogIHRtX2NyZWRpdHMoIsKpIE1hcGJveCwgwqkgT3BlblN0cmVldE1hcCIsIHBvc2l0aW9uID0gYygibGVmdCIsICJCT1RUT00iKSkgKw0KICB0bV9sYXlvdXQoDQogICAgbWFpbi50aXRsZSA9ICJNZWQuIENhbXB1cyBUb3RhbCBDcmltZSAtIEF1Z3VzdCAyMDE5IiwNCiAgICBmcmFtZSA9IEZBTFNFLA0KICAgIGxlZ2VuZC5iZy5jb2xvciA9ICJ3aGl0ZSIsIA0KICAgIGxlZ2VuZC5mcmFtZT1UUlVFLA0KICAgIGxlZ2VuZC5vdXRzaWRlID0gVFJVRSwNCiAgICBsZWdlbmQucG9zaXRpb24gPSBjKCJyaWdodCIsICJib3R0b20iKSkgDQoNCmN3ZV9tY190bQ0KYGBgDQojIyMjIyMgQ29ydGV4DQoNCmBgYHtyIENvcnRleCBUb3RhbCBDcmltZX0NCmN0eF9jcmltZXMgPC0gc3RfaW50ZXJzZWN0aW9uKGNyaW1lczE5X3NmLCBjb3J0ZXgpDQoNCmN3ZV9jdHhfdG0gPC0gdG1fc2hhcGUoY3R4X3RpbGVzKSArDQogIHRtX3JnYigpICsNCiAgbmhvb2RzX3NmICU+JQ0KICBmaWx0ZXIoLiwgbmVpZ2hib3Job29kID09IDM4KSAlPiUgDQogIHRtX3NoYXBlKCkgKw0KICAgIHRtX2JvcmRlcnMoY29sID0gImJsYWNrIiwgDQogICAgICAgICAgICAgICBsd2QgPSAyLCANCiAgICAgICAgICAgICAgIGx0eSA9ICJkYXNoZWQiKSArDQogIHRtX3NoYXBlKGNvcnRleCkgKw0KICAgIHRtX2ZpbGwoY29sID0gIiM5ZWNhZTEiLCANCiAgICAgICAgICAgIGFscGhhID0gLjUpICsNCiAgICB0bV9ib3JkZXJzKGNvbCA9ICJibGFjayIsIA0KICAgICAgICAgICAgICAgbHdkID0gMSwgDQogICAgICAgICAgICAgICBsdHkgPSAic29saWQiKSArDQogIHRtX3NoYXBlKGN0eF9jcmltZXMpICsNCiAgICB0bV9idWJibGVzKHNpemUgPSAuMjUsIA0KICAgICAgICAgICAgICAgY29sID0gImNyaW1lQ2F0TmFtZSIsIA0KICAgICAgICAgICAgICAgcGFsZXR0ZSA9ICJTZXQxIiwgDQogICAgICAgICAgICAgICB0aXRsZS5jb2wgPSAiUGFydCAxIENyaW1lcyIpICsNCiAgdG1fY3JlZGl0cygiwqkgTWFwYm94LCDCqSBPcGVuU3RyZWV0TWFwIiwgcG9zaXRpb24gPSBjKCJsZWZ0IiwgIkJPVFRPTSIpKSArDQogIHRtX2xheW91dCgNCiAgICBtYWluLnRpdGxlID0gIkNvcnRleCBUb3RhbCBDcmltZSAtIEF1Z3VzdCAyMDE5IiwNCiAgICBmcmFtZSA9IEZBTFNFLA0KICAgIGxlZ2VuZC5iZy5jb2xvciA9ICJ3aGl0ZSIsIA0KICAgIGxlZ2VuZC5mcmFtZT1UUlVFLA0KICAgIGxlZ2VuZC5vdXRzaWRlID0gVFJVRSwNCiAgICBsZWdlbmQucG9zaXRpb24gPSBjKCJyaWdodCIsICJib3R0b20iKSkgDQoNCmN3ZV9jdHhfdG0NCmBgYA0KDQoNCiMjIyMjIEJvdGFuaWNhbCBIZWlnaHRzDQoNCmBgYHtyIEJvdGFuaWNhbCBIZWlnaHRzIFRvdGFsIENyaW1lfQ0KYm90X3RvdGFsX3RtIDwtIHRtX3NoYXBlKGJvdF90aWxlcykgKw0KICB0bV9yZ2IoKSArDQogIG5ob29kc19zZiAlPiUNCiAgZmlsdGVyKC4sIG5laWdoYm9yaG9vZCA9PSAyOCkgJT4lIA0KICB0bV9zaGFwZSgpICsNCiAgICB0bV9maWxsKGNvbCA9ICIjOWVjYWUxIiwgDQogICAgICAgICAgICBhbHBoYSA9IC41KSArDQogICAgdG1fYm9yZGVycyhjb2wgPSAiYmxhY2siLCANCiAgICAgICAgICAgICAgIGx3ZCA9IDIsIA0KICAgICAgICAgICAgICAgbHR5ID0gImRhc2hlZCIpICsNCiAgZmlsdGVyKGNyaW1lczE5X3NmLCANCiAgICAgICAgIG5laWdoYm9yaG9vZCA9PSAyOCkgJT4lDQogIHRtX3NoYXBlKCkgKw0KICAgIHRtX2J1YmJsZXMoc2l6ZSA9IC4yNSwgDQogICAgICAgICAgICAgICBjb2wgPSAiY3JpbWVDYXROYW1lIiwgDQogICAgICAgICAgICAgICBwYWxldHRlID0gIlNldDEiLCANCiAgICAgICAgICAgICAgIHRpdGxlLmNvbCA9ICJQYXJ0IDEgQ3JpbWVzIikgKw0KICB0bV9jcmVkaXRzKCLCqSBNYXBib3gsIMKpIE9wZW5TdHJlZXRNYXAiLCBwb3NpdGlvbiA9IGMoImxlZnQiLCAiQk9UVE9NIikpICsNCiAgdG1fbGF5b3V0KA0KICAgIG1haW4udGl0bGUgPSAiQm90YW5pY2FsIEhlaWdodHMgVG90YWwgQ3JpbWUgLSBBdWd1c3QgMjAxOSIsDQogICAgZnJhbWUgPSBGQUxTRSwNCiAgICBsZWdlbmQuYmcuY29sb3IgPSAid2hpdGUiLCANCiAgICBsZWdlbmQuZnJhbWU9VFJVRSwNCiAgICBsZWdlbmQub3V0c2lkZSA9IFRSVUUsDQogICAgbGVnZW5kLnBvc2l0aW9uID0gYygicmlnaHQiLCAiYm90dG9tIikpIA0KDQpib3RfdG90YWxfdG0NCmBgYA0KDQoNCiMjIyMjIERpc3RyaWN0IDIgRGVuc2l0eSBNYXBzDQpgYGB7ciBHZW5lcmF0ZSBEaXN0cmljdCAyIERlbnNpdHkgTWFwc30NCmRzdDJfcmF0ZU1hcCA8LSB0bV9zaGFwZShkc3QyX3RpbGVzKSArDQogIHRtX3JnYigpICsNCiAgdG1fc2hhcGUoZHN0XzJfcG9wKSArDQogIHRtX3BvbHlnb25zKGNvbCA9ICJjcmltZVJhdGUiLA0KICAgICAgICAgICAgICBwYWxldHRlID0gIkJ1UHUiLA0KICAgICAgICAgICAgICBzdHlsZSA9ICJqZW5rcyIsDQogICAgICAgICAgICAgIHRpdGxlID0gIkNyaW1lcyBwZXIgMSwwMDAgUmVzaWRlbnRzIikgKw0KICB0bV90ZXh0KCJuZWlnaGJvcmhvb2QiLCBzaGFkb3c9VFJVRSkgKw0KICB0bV9sYXlvdXQoDQogICAgbWFpbi50aXRsZSA9ICJEaXN0cmljdCAyIENyaW1lIFJhdGVzIC0gQXVndXN0IDIwMTkiLA0KICAgIGZyYW1lID0gRkFMU0UsDQogICAgbGVnZW5kLmJnLmNvbG9yID0gIndoaXRlIiwgDQogICAgbGVnZW5kLmZyYW1lPVRSVUUsDQogICAgbGVnZW5kLm91dHNpZGUgPSBUUlVFLA0KICAgIGxlZ2VuZC5wb3NpdGlvbiA9IGMoInJpZ2h0IiwgImJvdHRvbSIpKSANCg0KZHN0Ml9yYXRlTWFwDQpgYGANCg0KYGBge3IgR2VuZXJhdGUgRGlzdHJpY3QgNSBEZW5zaXR5IE1hcHN9DQpkc3Q1X3JhdGVNYXAgPC0gdG1fc2hhcGUoZHN0NV90aWxlcykgKw0KICB0bV9yZ2IoKSArDQogIHRtX3NoYXBlKGRzdF81X3BvcCkgKw0KICB0bV9wb2x5Z29ucyhjb2wgPSAiY3JpbWVSYXRlIiwNCiAgICAgICAgICAgICAgcGFsZXR0ZSA9ICJCdVB1IiwNCiAgICAgICAgICAgICAgc3R5bGUgPSAiamVua3MiLA0KICAgICAgICAgICAgICB0aXRsZSA9ICJDcmltZXMgcGVyIDEsMDAwIFJlc2lkZW50cyIpICsNCiAgdG1fdGV4dCgibmVpZ2hib3Job29kIiwgc2hhZG93PVRSVUUpICsNCiAgdG1fbGF5b3V0KA0KICAgIG1haW4udGl0bGUgPSAiRGlzdHJpY3QgNSBDcmltZSBSYXRlcyAtIEF1Z3VzdCAyMDE5IiwNCiAgICBmcmFtZSA9IEZBTFNFLA0KICAgIGxlZ2VuZC5iZy5jb2xvciA9ICJ3aGl0ZSIsIA0KICAgIGxlZ2VuZC5mcmFtZT1UUlVFLA0KICAgIGxlZ2VuZC5vdXRzaWRlID0gVFJVRSwNCiAgICBsZWdlbmQucG9zaXRpb24gPSBjKCJyaWdodCIsICJib3R0b20iKSkgDQoNCmRzdDVfcmF0ZU1hcA0KYGBgDQoNCg0KDQojIyMgU2F2ZSBNYXBzDQoNCmBgYHtyIFNhdmUgRlBTRSBNYXBzLCBlY2hvID0gRkFMU0UsIGluY2x1ZGUgPSBGQUxTRX0NCnRtYXBfc2F2ZShmcHNlX3RvdGFsX3RtLCBmaWxlID0gaGVyZSgicmVzdWx0cy9mcHNlLzIwMTkvYXVndXN0L2Zwc2VfdG90YWxfY3JpbWVzLmpwZWciKSwgZHBpID0gNTAwKQ0KdG1hcF9zYXZlKGZwc2VfZG5fdG0sIGZpbGUgPSBoZXJlKCJyZXN1bHRzL2Zwc2UvMjAxOS9hdWd1c3QvZnBzZV9kYXlfbmlnaHQuanBlZyIpLCBkcGkgPSA1MDApDQp0bWFwX3NhdmUoZnBzZV92bG50X3RtLCBmaWxlID0gaGVyZSgicmVzdWx0cy9mcHNlLzIwMTkvYXVndXN0L2Zwc2VfdmxudC5qcGVnIiksIGRwaSA9IDUwMCkNCnRtYXBfc2F2ZShmcHNlX2Rlbl90bSwgZmlsZSA9IGhlcmUoInJlc3VsdHMvZnBzZS8yMDE5L2F1Z3VzdC9mcHNlX2RlbnNpdHkuanBlZyIpLCBkcGkgPSA1MDApDQp0bWFwX3NhdmUoZnBzZV9ncm92ZV90bSwgZmlsZSA9IGhlcmUoInJlc3VsdHMvZnBzZS8yMDE5L2F1Z3VzdC9mcHNlX2dyb3ZlLmpwZWciKSwgZHBpID0gNTAwKQ0KYGBgDQoNCmBgYHtyIFNhdmUgQ1dFIE1hcHMsIGVjaG8gPSBGQUxTRSwgaW5jbHVkZSA9IEZBTFNFfQ0KdG1hcF9zYXZlKGN3ZV90b3RhbF90bSwgZmlsZSA9IGhlcmUoInJlc3VsdHMvY3dlLzIwMTkvYXVndXN0L2N3ZV90b3RhbF9jcmltZXMuanBlZyIpLCBkcGkgPSA1MDApDQp0bWFwX3NhdmUoY3dlX2RuX3RtLCBmaWxlID0gaGVyZSgicmVzdWx0cy9jd2UvMjAxOS9hdWd1c3QvY3dlX2RheV9uaWdodC5qcGVnIiksIGRwaSA9IDUwMCkNCnRtYXBfc2F2ZShjd2VfdmxudF90bSwgZmlsZSA9IGhlcmUoInJlc3VsdHMvY3dlLzIwMTkvYXVndXN0L2N3ZV92bG50LmpwZWciKSwgZHBpID0gNTAwKQ0KdG1hcF9zYXZlKGN3ZV9kZW5fdG0sIGZpbGUgPSBoZXJlKCJyZXN1bHRzL2N3ZS8yMDE5L2F1Z3VzdC9jd2VfZGVuLmpwZWciKSwgZHBpID0gNTAwKQ0KdG1hcF9zYXZlKGN3ZV9tY190bSwgZmlsZSA9IGhlcmUoInJlc3VsdHMvY3dlLzIwMTkvYXVndXN0L2N3ZV9tYy5qcGVnIiksIGRwaSA9IDUwMCkNCnRtYXBfc2F2ZShjd2VfY3R4X3RtLCBmaWxlID0gaGVyZSgicmVzdWx0cy9jd2UvMjAxOS9hdWd1c3QvY3dlX2N0eC5qcGVnIiksIGRwaSA9IDUwMCkNCmBgYA0KDQpgYGB7ciBTYXZlIEJPVCBNYXAsIGVjaG8gPSBGQUxTRSwgaW5jbHVkZSA9IEZBTFNFfQ0KdG1hcF9zYXZlKGN3ZV90b3RhbF90bSwgZmlsZSA9IGhlcmUoInJlc3VsdHMvYm90LzIwMTkvYm90X2F1Z190b3RhbC5qcGVnIiksIGRwaSA9IDUwMCkNCmBgYA0KDQpgYGB7ciBTYXZlIERpc3RyaWN0IERlbnNpdHkgTWFwcywgZWNobyA9IEZBTFNFLCBpbmNsdWRlID0gRkFMU0V9DQp0bWFwX3NhdmUoZHN0Ml9yYXRlTWFwLCBmaWxlID0gaGVyZSgicmVzdWx0cy9kaXN0cmljdC0yLzIwMTkvZHN0Ml9hdWdfcmF0ZXMuanBlZyIpLCBkcGkgPSA1MDApDQp0bWFwX3NhdmUoZHN0NV9yYXRlTWFwLCBmaWxlID0gaGVyZSgicmVzdWx0cy9kaXN0cmljdC01LzIwMTkvZHN0NV9hdWdfcmF0ZXMuanBlZyIpLCBkcGkgPSA1MDApDQpgYGANCg0KDQojIyMgQ2xlYW4gV29ya3NwYWNlIA0KDQpgYGB7ciBSZW1vdmUgT2JqZWN0cyBmcm9tIEVudmlyb25tZW50fQ0Kcm0oZnBzZV90b3RhbF90bSwgZnBzZV9kbl90bSwgZnBzZV92bG50X3RtLCBmcHNlX2Rlbl90bSwgZnBzZV9ncm92ZV90bSwgY3dlX3RvdGFsX3RtLCBjd2VfZG5fdG0sIGN3ZV92bG50X3RtLCBjd2VfZGVuX3RtLCBjd2VfbWNfdG0sIGN3ZV9jdHhfdG0sIGJvdF90b3RhbF90bSwgZnBzZV90aWxlcywgY3dlX3RpbGVzLCBib3RfdGlsZXMsIGRicF90aWxlcywgc2RiX3RpbGVzLCB3ZV90aWxlcywgdnBfdGlsZXMsIGFjX3RpbGVzLCBmcF90aWxlcywgbHBfdGlsZXMsIHZkX3RpbGVzLCBtY190aWxlcywgY3R4X3RpbGVzLCBncnZfdGlsZXMsIGRzdF8yLCBkc3RfNSwgZHN0Ml90aWxlcywgZHN0NV90aWxlcykNCmBgYA0KDQo=